参考博文:Thread中interrupted()方法和isInterrupted()方法区别总结
廖雪峰的参考博文,最靠谱的做法
首先讲 interrupt() 方法:
interrupt()方法只是改变中断状态,不会中断一个正在运行的线程。需要用户自己去监视线程的状态为并做处理。
-
interrupt 中断操作时,非自身打断需要先检测是否有中断权限,这由jvm的安全机制配置;
-
如果线程处于sleep, wait, join 等状态,那么线程将立即退出被阻塞状态,并抛出一个
InterruptedException
异常; -
如果线程处于I/O阻塞状态,将会抛
ClosedByInterruptException
(IOException的子类)异常; -
如果线程在Selector上被阻塞,select方法将立即返回;
-
如果非以上情况,将直接标记 interrupt 状态;
注意:interrupt 操作不会打断所有阻塞,只有上述阻塞情况才在jvm的打断范围内,如处于锁阻塞的线程,不会受 interrupt中断;
interrupted()和isInterrupted()方法说明
isInterrupted()
,用来判断当前线程的中断状态(true or false)。
interrupted()
是个Thread的static方法,内部调用了isInterrupted()方法,所以他首先会判断线程是否处于中断状态,其次他还可以用来恢复中断状态。
下面是源码说明:
public boolean isInterrupted() {
return isInterrupted(ClearInterrupted:false); //表示并不会重置中断标志位。
}
public static boolean interrupted() {
return currentThread().isInterrupted(ClearInterrupted:true); //表示会重置中断标志位
}
上面两个方法调用的方法如下:
作用是:测试某个线程是否被中断。中断状态将根据传递的clear的值重置或不重置----所以有两个功能;
1.首先返回的是线程是否被中断,
2.中断状态是否被重置取决于传入的值。
/**
* Tests if some Thread has been interrupted. The interrupted state
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
private native boolean isInterrupted(boolean ClearInterrupted);
测试
阻塞情况下中断,抛出异常后线程恢复非中断状态,即 interrupted = false
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Task("1"));
t.start();
t.interrupt();
}
static class Task implements Runnable{
String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("thread has been interrupt!");
}
System.out.println("isInterrupted: " + Thread.currentThread().isInterrupted());
System.out.println("task " + name + " is over");
}
}
}
输出:
thread has been interrupt!
isInterrupted: false
task 1 is over
调用Thread.interrupted() 方法后线程恢复非中断状态
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Task("1"));
t.start();
t.interrupt();
}
static class Task implements Runnable{
String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("first :" + Thread.interrupted());
System.out.println("second:" + Thread.interrupted());
System.out.println("task " + name + " is over");
}
}
}
输出结果
first :true
second:false
task 1 is over
总结
所以想要中断一个线程:需要堵塞状态(sleep(),wait(),join()
)+线程中断标志(interrupt()
)两者配合使用,那么该线程将抛出一个 InterruptedException中断异常(该线程必须事先预备好处理此异常),从而提早地终结被阻塞状态。如果线程没有被阻塞,这时调用 interrupt()将不起作用,直到执行到wait(),sleep(),join()时,才马上会抛出 InterruptedException。
无论是先中断还是先阻塞最后都能达到停止线程的目的----------异常中断法。