考虑以下JUnit测试:
@Test
public void testSettingInterruptFlag() throws InterruptedException {
Thread blockingThread = new Thread(new Runnable() {
@Override
public synchronized void run() {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
blockingThread.start();
blockingThread.interrupt();
blockingThread.join();
assertTrue(blockingThread.isInterrupted());
}
Run Code Online (Sandbox Code Playgroud)
即使设置了中断状态,测试也会失败.我怀疑该行blockingThread.join();重置了标志,但即使用Thread.sleep(3000);测试替换该行仍然失败.这种行为记录在哪里吗?
我们看到的是线程的中断状态在该线程完成时被清除。它没有记录在http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html 中,因此可以被视为规范或实现错误。
Java 14 中已修复此问题。
Thread.isInterruptedtrue如果线程被中断,则返回,即使线程不活动。请参阅 Oracle 的发行说明和JDK-8229516。
规范
java.lang.Thread::interrupt允许实现仅跟踪活动线程的中断状态,而以前这就是发生的情况。从此版本开始,a 的中断状态始终Thread可用t,并且如果您在线程启动之前或终止之后中断线程t.isInterrupted()true。
以下段落已添加到 javadoc 中Thread#interrupt:
在 JDK 参考实现中,不活动的线程的中断仍然记录发出了中断请求,并将通过以下方式报告:
interrupted和报告isInterrupted()。
因此问题中的测试成功运行在:
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment (build 14.0.2+12)
OpenJDK 64-Bit Server VM (build 14.0.2+12, mixed mode)
Run Code Online (Sandbox Code Playgroud)
中断标志作为字段存储在Thread类中:
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment (build 14.0.2+12)
OpenJDK 64-Bit Server VM (build 14.0.2+12, mixed mode)
Run Code Online (Sandbox Code Playgroud)
和isInterrupted只是返回标志:
public boolean isInterrupted() {
return interrupted;
}
Run Code Online (Sandbox Code Playgroud)
之前它委托给一个native isInterrupted(boolean)方法
| 归档时间: |
|
| 查看次数: |
464 次 |
| 最近记录: |