java中线程在运行过程中可以通过interrupt方法进行中断,这里需要提到几个的注意点:
1、中断状态是可以被清除或者说恢复的
2、中断请求不是一定会被响应(如io包中的一些操作,只会标记中断状态,而对线程并没有实际影响)
3、调用interrupt并不是立即中断线程执行,而是传递了中断请求
下面看demo
public class MyInterrupt implements Runnable{
private volatile int i = 0;
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(i++ + String.valueOf(Thread.currentThread().isInterrupted()));
//Point1:如果在这里调用中断请求,程序会在i=20时抛出异常,但不会中断,线程继续执行下去
//if (i == 20) {
// cancel();
//}
try {
Thread.sleep(100);
//this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
//Point2:在此处调用中断请求,最后打印 19:false isInterrupted()返回true所以不在进入循环体
if (i == 20) {
cancel();
}
}
}
public void cancel(){
Thread.currentThread().interrupt();
}
public static void main(String[] args) {
new Thread(new MyInterrupt()).start();
}
}
在point1处去中断时候为什么程序会继续执行,这里我们看下sleep方法以及wait方法的doc
/**
* Causes the currently executing thread to sleep (temporarily cease
* execution) for the specified number of milliseconds, subject to
* the precision and accuracy of system timers and schedulers. The thread
* does not lose ownership of any monitors.
*
* @param millis
* the length of time to sleep in milliseconds
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public static native void sleep(long millis) throws InterruptedException;
在jdk8中的注释中我们可以发现@throws中说明了,如果任意线程发出了中断请求,当抛出InterruptedException异常后,中断状态会被清除,也就是说该线程不会被中断,再次调用isInterrupted方法则会返回false。