java - 线程通过调用interrupt()被中断,但是Thread.isInterrupted()返回false

标签 java multithreading concurrency interrupted-exception interruption

我正在使用以下测试代码测试 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(...)它打印出工作线程的中断状态。自从我捕获了InterruptedExceptionrun() ,我想我应该收到 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/

相关文章:

Java URL 正则表达式不匹配

java - 使用 Java 8 更好地替换嵌套 for 循环中的代码

java - 访问说明符和访问修饰符有什么区别?

java - 使用预定义 key 锁定的竞争条件解决方案

java - Google Kick Start 2020 A 轮中获取样本失败

Java 进程 - 无法解压缩 zip 文件

c++ - 如何在 QT 中使用互斥锁定线程开始轮询?

c# - WinForm 多线程。是否使用 backgroundWorker?

azure - Windows Azure 中的异步循环任务计划程序

concurrency - 如何退出 channel 范围/收集结果