java multithreading basic api usage
The difference between isInterrupted and interrupted
isInterrupted will only return the thread state without changing, while interrupted will reset the state,
public class MyThread11 extends Thread{ public static void main(String[] args) throws InterruptedException { Thread.currentThread().interrupt(); System.out.println("是否停止?"+Thread.currentThread().isInterrupted()); System.out.println("Stop?"+Thread.interrupted()); System.out.println("Stop?"+Thread.interrupted()); } }
The output is:
stop? true stop? true Stop? false
How to stop the thread:
1. Use the interrupt() and isInterrupted() methods to judge, return or catch abnormal termination
Note that with the interrupt() method, the thread cannot be stopped
public class MyThread11 extends Thread{ public static void main(String[] args) throws InterruptedException { MyThread11 mt=new MyThread11(); mt.start(); Thread.sleep(500); mt.interrupt(); System.out.println("Stop 1?"+mt.isInterrupted()); System.out.println("Stop 1?"+mt.isInterrupted()); } public void run(){ for(int i=0;i<10_0000;i++){ if(this.isInterrupted()){ System.out.println("interrupted status, exit!"); } System.out.println("i="+i); // Thread.sleep(1000); } System.out.println("for 下面"); } }
The output is: the following is still executing
interrupted state, exit! i=95164 interrupted state, exit! i=95165
So use the method of throwing exceptions and capturing to terminate the subsequent statement of the thread
public class MyThread11 extends Thread{ public static void main(String[] args) throws InterruptedException { MyThread11 mt=new MyThread11(); mt.start(); Thread.sleep(500); mt.interrupt(); System.out.println("Stop 1?"+mt.isInterrupted()); System.out.println("Stop 1?"+mt.isInterrupted()); } public void run(){ try{ for(int i=0;i<10_0000;i++){ if(this.isInterrupted()){ System.out.println("interrupted status, exit!"); throw new InterruptedException("manually throw exception"); } System.out.println("i="+i); // Thread.sleep(1000); } System.out.println("for 下面"); }catch(InterruptedException e){ e.printStackTrace (); } } }
i=84326 interrupted state, exit! stop 1? true stop 1? true java.lang.InterruptedException: Manually throw exception at MyThread11.run(MyThread11.java:15)
So interrupt() interrupts the thread, it does not interrupt the execution of the thread, it just changes the state,
Need to add judgment, and then manually throw abnormal termination,
Or use return to stop subsequent statement execution, as follows:
public class InterruptWithReturn extends Thread{ private int i=0; public static void main(String[] args) throws InterruptedException { InterruptWithReturn mt=new InterruptWithReturn(); mt.start(); Thread.sleep(200); mt.interrupt(); } public void run(){ while(true){ if(this.isInterrupted()){ System.out.println("stoped by interrupt"); break; } i++; System.out.println(i); } } }
In addition, when the sleep method is executing, an exception will be reported when it encounters an interrupt, which can be captured, and subsequent statements cannot be executed.
/** * * Interrupt the loop first, then enter the catch statement of sleep */ public class MyThread13 extends Thread{ public static void main(String[] args) throws InterruptedException { MyThread13 mt=new MyThread13(); mt.start(); // Thread.sleep(500); mt.interrupt(); System.out.println("Stop 1?"+mt.isInterrupted()); System.out.println("Stop 1?"+mt.isInterrupted()); } public void run(){ try { for(int i=0;i<50_000;i++){ System.out.println(i); } Thread.sleep(20000); System.out.println("after sleep"); } catch (InterruptedException e) { System.out.println("Interrupt first, the for loop continues until it encounters the sleep method and catches an exception, then stops" +this.isInterrupted()); e.printStackTrace (); } } }
49998 49999 First interrupt, the for loop continues, until the sleep method is encountered, the exception is caught, and the false is stopped. java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at MyThread13.run(MyThread13.java:19)
2, stop() method forcibly stop
The reason why it is not recommended is that forcing stop will cause some cleanup work at the end of the thread to not be performed, such as unlocking the locked object, resulting in out of synchronization. In addition, the three methods of stop.suspend.resume have been deprecate and will no longer be supported in the future.
3, use extra markers to stop
Use thread communication, add judgment, and stop the thread at the appropriate time
public class MyThread16 extends Thread{ private boolean isRun=true; public boolean isRun() { return isRun; } public void setRun(boolean isRun) { this.isRun = isRun; } public static void main(String[] args) throws InterruptedException { MyThread16 mt=new MyThread16(); mt.start(); Thread.sleep(100); if(mt.isRun){ mt.setRun(false); } System.out.println(mt.isAlive()); System.out.println(mt.isInterrupted()); } public void run(){ while(true){ System.out.println("running..."); if(!isRun){ System.out.println("stop"); return; } } } }
suspend和resume
package suspendAndResume; public class MyThread extends Thread { private long i=0; public long getI() { return i; } public void setI(long i) { this.i = i; } @Override public void run(){ while(true){ i++; } } }
package suspendAndResume; public class Run { public static void main(String[] args) { try{ MyThread mt=new MyThread(); mt.start(); //A Thread.sleep(5000); mt.suspend(); System.out.println("A="+System.currentTimeMillis()+" i="+mt.getI());//A=1525146789091 i=2436609039 Thread.sleep(5000); System.out.println("A="+System.currentTimeMillis()+" i="+mt.getI());//A=1525146794091 i=2436609039 mt.resume(); Thread.sleep(5000); System.out.println("B="+System.currentTimeMillis()+" i="+mt.getI());//B=1525146799091 i=4862628335 mt.suspend(); Thread.sleep(5000); System.out.println("B="+System.currentTimeMillis()+" i="+mt.getI());//B=1525146804091 i=4862666032 }catch(InterruptedException e){ } } }
Disadvantages of suspend and resume:
1, monopoly
package suspendAndResume; public class SynchronizedObject { synchronized public void printString(){ System.out.println("beging---"); if(Thread.currentThread().getName().equals("a")){ System.out.println("a线程suspend"); Thread.currentThread().suspend(); } System.out.println("end---"); } }
package suspendAndResume; public class Run2 { public static void main(String[] args){ try{ final SynchronizedObject object=new SynchronizedObject(); Thread t1=new Thread(){ public void run(){ object.printString(); } }; t1.setName("a"); t1.start(); Thread.sleep(1000); Thread t2=new Thread(){ public void run(){ System.out.println("t2 tries to enter the printString method"); object.printString(); System.out.println("Begin is not printed because printString is exclusive to t1 and t1 is suspended"); } }; t2.start(); }catch(InterruptedException e){ e.printStackTrace (); } } }
committed--- a thread suspend t2 tries to enter the printString method
The program will always block here and cannot proceed. In addition, the exclusive use of the println method will cause the println of other threads to block,
Suspend causes multi-thread asynchrony
package suspendAndResume; public class MyObject { private String username="1"; private String passwd="1111"; public void setValue(String u,String p){ this.username=u; if("a".equals(Thread.currentThread().getName())){ System.out.println("a线程suspend"); Thread.currentThread().suspend(); } this.passwd=p; } public void printUAndP () { System.out.println(username+":"+passwd); } }
package suspendAndResume; /* * Demonstrate the problem that the suspend method causes asynchrony */ public class Run4 { public static void main(String[] args) throws InterruptedException{ MyObject mo=new MyObject(); Thread t1=new Thread(){ @Override public void run(){ mo.setValue("a", "aaa"); } }; t1.setName("a"); t1.start();//a thread will hang all the time, causing the program to block, and passwd is still the initial value, Thread.sleep(1000);//sleep main进程, Thread t2=new Thread(){ @Override public void run(){ mo.printUAndP (); } }; t2.start(); } }
yield
Example:
package yield; public class MyThread extends Thread { @Override public void run(){ long sum=0; long begin=System.currentTimeMillis(); for(int i=0;i<50_0000;i++){ sum+=i; // output after comment: // sum=124999750000 // time: 2ms // uncomment output: // sum=124999750000 // time: 62ms Thread.yield(); } long end=System.currentTimeMillis(); System.out.println("sum="+sum); System.out.println("用时:"+(end-begin)+"ms"); } }
package yield; /* * By looping yield, the time-consuming increase, demonstrating the function of yield giving up cpu time, */ public class Run { public static void main(String[] args) { MyThread mt=new MyThread(); mt.start(); } }
priority:
Source code:
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess ();
/ / Determine whether it is greater than 10 and less than 0
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
//The set thread priority cannot be higher than the maximum priority of the group where the thread is located,
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
The priorities are:
Regularity: High priority (1-10, the higher the priority, the higher the priority) gets the CPU time first,
Randomness: It is not that the thread with higher priority must be executed first than the thread with lower priority
In terms of performance, the execution speed of the thread body with high priority is faster, because more CPU time is obtained
daemon
The setDaemon(true) method is set to the daemon process. When there are no other non-daemon processes, the daemon process does not need to exist and will automatically end.
Reference: "Core Technology of Java Multithreaded Programming"