Java线程执行异常:调用interrupt后仍输出t7 executing...的原因
问题分析与解答
核心原因
你遇到的现象由两个关键因素导致:
线程调度的异步性
main线程调用t7.interrupt()后,并不会立刻暂停t7的执行,而是会继续运行自身后续的打印语句。由于System.out.println是线程安全的(内部持有同步锁),main线程在执行那两次状态打印时会占用锁,导致t7暂时无法输出内容,直到main线程释放锁后,t7才会继续执行。Thread.interrupted()的特性
这个静态方法会读取当前线程的中断状态,同时立即清除中断标记。当t7终于获得执行机会时,它会先完成当前循环周期的剩余代码(也就是输出t7 executing...),然后进入循环条件判断:此时Thread.interrupted()返回true(因为之前main线程触发了中断),同时把中断状态重置为false。!true的结果为false,循环退出,最终输出t7 stopped!。
另外两次isInterrupted()结果不同的原因:
- 第一次调用时,t7的中断状态还未被
Thread.interrupted()清除,所以返回true; - 当t7执行了
Thread.interrupted()后,中断标记被清除,因此第二次调用返回false。
代码修正(避免多余输出)
如果希望t7收到中断后立即停止循环,不再输出t7 executing...,可以改用不清除中断标记的isInterrupted()方法判断,同时在循环体开头增加中断检查:
public class ThreadTest { public static void main (String[] args){ Thread t7 = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { // 循环体开头额外检查中断,避免执行到一半才响应 if (Thread.currentThread().isInterrupted()) { break; } System.out.println("t7 executing..."); } System.out.println("t7 stopped!"); }); t7.start(); for (int i = 0; i<10; i++){ System.out.println("Waiting for t7 to be interrupted..."); } t7.interrupt(); System.out.println("t7.isInterrupted: " + t7.isInterrupted()); // 等待t7执行完毕再检查最终状态 try { t7.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t7.isInterrupted at finish: " + t7.isInterrupted()); } }
关键方法区别
Thread.interrupted():静态方法,返回当前线程中断状态,会清除中断标记;ThreadcurrentThread().isInterrupted():实例方法,返回当前线程中断状态,不会清除中断标记。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

