我正在使用以下测试代码测试 InterruptedException:
Runnable runMe = new Runnable() {
@Override
public void run() {
for(int i=0; i<6; i++) {
System.out.println("i = "+i);
if(i==3) {
System.out.println("i==3, Thread = "
+Thread.currentThread().getId());
//I invoke interrupt() on the working thread.
Thread.currentThread().interrupt();
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
//I caught InterruptedException
System.out.println(Thread.currentThread().getId()
+ " is interrupted!");
Thread.currentThread().interrupt();
}
}
}
}
};
Thread workingThread = new Thread(runMe);
workingThread.start();
try {
workingThread.join();
} catch (InterruptedException e) {
//Swallow
}
//the following log shows me workingThread.isInterrupted() is false, why?
System.out.println("workingThread("
+ workingThread.getId()+") interrupted ? "
+ workingThread.isInterrupted());
在 run()
,我interrupt()
当前工作线程,并捕获了 InterruptedException
。
在主线程中,我的最后一行代码是 System.out.println(...)
它打印出工作线程的中断状态。自从我捕获了InterruptedException
在run()
,我想我应该收到 workingThread.isInterrupted()
的消息是正确,但我得到错误,为什么?
最佳答案
甲骨文的Java concurrency tutorial说(我添加了强调):
The Interrupt Status Flag
The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
你看到的是线程被中断,退出的方法是 join (实际上 join 是通过调用 Object.wait 实现的,所以我希望堆栈跟踪会显示 wait 是抛出异常的方法from),并且该标志被清除,就像教程中所说的那样。
由异常处理程序决定是否再次设置线程的中断状态标志。除非处理程序被编码为执行不同的操作,否则默认假设是异常已被处理并且不再需要设置标志。
API documentation for Thread#interrupt与此一致:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
我有一个答案,更详细地解释了为什么要这样设计中断 here .
关于java - 线程通过调用interrupt()被中断,但是Thread.isInterrupted()返回false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26429672/