要弄明白 interrupt,首先要了解如下几点:java
Java中线程间是协做式,而非抢占式. 调用一个线程的interrupt() 方法中断一个线程,并非强行关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断,由线程自己决定。ide
isInterrupted() 断定当前线程是否处于中断状态。spa
静态方法 interrupted() 断定当前线程是否处于中断状态,同时中断标志位改成 true。线程
若是方法里若是抛出中断异常 InterruptedException,则线程的中断标志位会被复位成false,若是确实是须要中断线程,要求咱们本身在catch语句块里再次调用interrupt()。code
Java 中全部的阻塞方法都会抛出 InterruptedExceptionorm
public class EndThread {
private static class UseThread extends Thread{
public UseThread(String name) {
super(name);
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
while(true) {
System.out.println(threadName+" is run!");
}
//System.out.println(threadName+" interrput flag is "+isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
Thread endThread = new UseThread("endThread");
endThread.start();
Thread.sleep(20);
endThread.interrupt();
}
}
复制代码
运行结果:get
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread is run!
...
复制代码
endThread 一直在运行,主线程调用 interrupt() 方法并无使 endThread 真正中断string
public class EndRunnable {
private static class UseRunnable implements Runnable{
@Override
public void run() {
String threadName = Thread.currentThread().getName();
while(Thread.currentThread().isInterrupted()) {
//若是真发生中断后,这行代码不会执行了
System.out.println(threadName+" is run!");
}
System.out.println(threadName+" interrupt flag is " +Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
UseRunnable useRunnable = new UseRunnable();
Thread endThread = new Thread(useRunnable,"endThread");
endThread.start();
Thread.sleep(20);
endThread.interrupt();
}
}
复制代码
运行结果:it
endThread interrupt flag is false
复制代码
经过 while(Thread.currentThread().isInterrupted()) 这种方式来控制循环能真正实现 interruptio
由上面两个例子论证了Java中线程间是协做式,而非抢占式
public class HasInterruptException {
private static SimpleDateFormat formater
= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss_SSS");
private static class UseThread extends Thread{
public UseThread(String name) {
super(name);
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
while(!isInterrupted()) {
try {
System.out.println("UseThread:"+formater.format(new Date()));
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println(threadName + " catch interrput flag is "
+ isInterrupted() + " at "
+ (formater.format(new Date())));
//方法里若是抛出InterruptedException,线程的中断标志位会被复位成false,
// 若是确实是须要中断线程,要求咱们本身在catch语句块里再次调用interrupt()。
interrupt();
e.printStackTrace();
}
System.out.println(threadName);
}
System.out.println(threadName+" interrput flag is " +isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
Thread endThread = new UseThread("HasInterrputEx");
endThread.start();
System.out.println("Main:"+formater.format(new Date()));
Thread.sleep(800);
System.out.println("Main begin interrupt thread:"+formater.format(new Date()));
endThread.interrupt();
}
}
复制代码
运行结果:
UseThread:2019-09-10 15:06:57_995
Main:2019-09-10 15:06:57_995
Main begin interrupt thread:2019-09-10 15:06:58_795
HasInterrputEx catch interrput flag is false at 2019-09-10 15:06:58_795
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.xiangxue.ch1.safeend.HasInterrputException$UseThread.run(HasInterrputException.java:28)
HasInterrputEx
HasInterrputEx interrput flag is true复制代码