捕获InterruptedException时,Thread.currentThread().interrupt()是否必要?
先拆解你的测试代码里的关键细节:你是在主线程中打印子线程的中断状态,而非在子线程的catch块内部检查。当主线程调用t.interrupt()后立刻打印,此时子线程可能还没进入catch块(sleep正在响应中断的过程中),所以中断标志还是true;但一旦子线程进入catch块,JVM已经自动把当前线程的中断标志清除了——你可以在catch块里加一行System.out.println(Thread.currentThread().isInterrupted());,会发现输出是false。
那被注释的Thread.currentThread().interrupt()到底有什么用?
首先明确规则:所有抛出InterruptedException的方法(比如
Thread.sleep()、Object.wait()),在抛出异常前都会自动清除当前线程的中断标志。这意味着,如果你不在catch块里重新设置中断标志,后续的代码(不管是你自己写的逻辑,还是其他可中断方法)都无法感知到这个线程曾经被中断过。举个实际场景:假设子线程在catch块之后还有循环逻辑,需要靠中断标志退出:
Thread t = new Thread(() -> { try { Thread.sleep(1000L); } catch (InterruptedException e) { // 没调用interrupt(),中断标志已被JVM清除 } // 后续循环,依赖中断标志判断是否退出 while (!Thread.currentThread().isInterrupted()) { // 执行任务逻辑 } });
这时候因为中断标志已经被清掉,循环会一直执行,不会因为之前的中断请求而退出。但如果在catch块里加上Thread.currentThread().interrupt(),循环就能检测到中断标志,正常终止。
- 另外,如果你的线程是被上层逻辑管理的(比如线程池),重新设置中断标志可以让上层代码感知到中断事件,做出对应的处理(比如线程池回收线程时的逻辑)。
总结:这行代码的核心作用是恢复中断状态——把被JVM清除的中断标志重新设置回来,让线程后续的逻辑或者上层代码能够正确响应这个中断请求。
内容的提问来源于stack exchange,提问作者Shivani S

