一共三个方法.
Thread.interrupt();//就是尝试中断本线程.将添加中断标志
Thread.isInterrupted();//查看本线程的中断标志,代表是否被中断.
Thread.static.interrupted();//静态方法,尝试中断本线程,但是中断标志会被清除.
看如下两段代码:
private void aaa() throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().isInterrupted());//false
Thread.currentThread().interrupt();//尝试中断,添加中断标志
System.out.println(Thread.currentThread().isInterrupted());//true
}
});
t.start();
}
private void bbb() throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().isInterrupted());//false
Thread.interrupted();//尝试中断,清空中断标志
System.out.println(Thread.currentThread().isInterrupted());//false
}
});
t.start();
}
可以看到他们的区别.
但是一个新的问题产生了.不是中断了吗?为什么后面的打印还可以执行?
好吧.这个得需要看文档.
文档上说了该中断方法会自上而下判断,如果符合条件,则执行该措施,且不向下穿透..
1.如果是其他线程调用该线程的中断,将执行checkAccess()方法,这可能会引起SecurityException.如果是线程本身调用自身的中断则没问题.
2.如果此时线程被wait(),join(),sleep()阻塞,那么将会抛出异常InterruptedException.中断状态清除.但LockSupport.part()没有说.
3.如果此时线程在IO中被阻塞,那么流通道将关闭,将抛出 java.nio.channels.ClosedByInterruptException.设置为中断状态.
4.如果此时线程在java.nio.channels.Selector中阻塞,那么线程将结果立即返回.设置为中断状态.
5.如果以上条件都不成立,则设置为中断状态.
而我们上面的举例貌似只有第五条符合,也就是只是设置为中断状态,其他都不会做.
我们再来看一个例子:这个例子就会符合上面第二条.抛出异常.状态清除.
其实抛出异常是终止线程的一个不错的方法.但要记得清理资源.更要注意异常会释放锁
private void sleep() throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().isInterrupted());//此时还主线程在sleep还未执行中断,false
try {
Thread.currentThread().sleep(20000);//在这里被中断,抛异常
System.out.println(Thread.currentThread().isInterrupted());//上句抛异常,这里就不会执行了.
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().isInterrupted());//中断标志被清除,false
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(1000);
t.interrupt();
}
再来个例子,看下io阻塞的情况,实际上这玩意跟上面说的第三个规则根本不一样
private void read() throws InterruptedException {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t = new Thread(runnable);
t.start();
Thread.sleep(1000);
t.interrupt();//完全没有用,该被阻塞的还是被阻塞,根本不抛异常.
}
书中好像说了阻塞流和synchronized这俩根本不会受到interrupt()的影响;
还有一个疑问.以上5个规则,一般都是命中第五个,可说第五个只是设置了中断状态,有什么意义呢?
其实可以这样用.
private void ccc() throws InterruptedException {
Runnable runnable = new Runnable() {
@Override
public synchronized void run() {
while(true){
if (Thread.currentThread().isInterrupted()){
//如果设置为中断,结束执行
return;
}
//业务代码
}
}
};
Thread t = new Thread(runnable);
t.start();
Thread.sleep(3000);
t.interrupt();//命令线程中断执行
}