虽然线程方法里面有个方法为interrupt(),即线程中断,但是并不是调用了线程中断,线程就真的中断了,如果线程在sleep中,则会被异常捕获,例子如下:
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (true) {
System.out.println(i);
i++;
if (Thread.currentThread().isInterrupted()) {
System.out.println("中断标识为真,我将中断等待");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("我被中断异常捕获");
}
}
}
});
thread.start();
Thread.sleep(3000);
thread.interrupt();
Thread.sleep(20 * 1000);
}
运行结果:
可以看到,程序并没有中断成功,反而被异常捕获,这时候,我们可以想到,在异常里执行中断,该线程才会中断下来:
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (true) {
System.out.println(i);
i++;
if (Thread.currentThread().isInterrupted()) {
System.out.println("中断标识为真,我将中断等待");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("我被中断异常捕获");
// 在异常里面增加中断方法
Thread.currentThread().interrupt();
}
}
}
});
thread.start();
Thread.sleep(3000);
thread.interrupt();
Thread.sleep(20 * 1000);
}
运行结果:
可以看到这个时候才真正中断下来。所以使用中断的时候,不但主线程要执行中断,而且在执行线程的重点异常处,也要增加中断。另外,如果线程在执行循环,则一定要增加if (thread.isInterrupted()),否则线程就算在异常里面又一次执行了中断,循环还是会继续执行,如下图:
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (true) {
System.out.println(i);
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("我被中断异常捕获");
// 在异常里面增加中断方法
Thread.currentThread().interrupt();
}
}
}
});
thread.start();
Thread.sleep(3000);
thread.interrupt();
Thread.sleep(20 * 1000);
}
运行结果:
因此如果有循环要记得判断一下中断标识。中断标识一种是直接调用isInterrupted()方法判断,另外还可以通过在线程里面设置一个volatile变量,通过修改这个变量来实现。