isInterrupted() 仍然 returns "false" 即使 Thread.State 在 Java 的线程中是 "TERMINATED" - 为什么?
isInterrupted() still returns "false" even after the Thread.State is "TERMINATED" in Java's Thread - why?
当线程终止时 (Thread.State.TERMINATED
) 它仍然没有被中断。为什么?
我找到了 this, and I found this,但都没有回答我的问题。我已经在 OpenJDK 11 和 Oracle JDK 16 上试过了 - 没有区别,相同结果.
我已经使用 Java 10 多年了,多线程任务对我来说一直很清楚;然而,不小心,我遇到了一些奇怪的事情(对我来说),我很想知道。
我明白,private volatile boolean interrupted;
只是 class Thread
的标志(字段),我可以将其与 interrupt()
结合使用以便编码isInterrupted()
得到 true
.
时的一些逻辑
但是,为什么 Thread.State.TERMINATED
state 不也创建相同的线程 interrupted
?
public class MainClass {
public static void main(String[] args) throws Exception {
Thread alfa = new Thread(() -> {
for (int i = 0; i < 3; i++) {
System.out.println(i + ". " + Thread.currentThread().getName() + " state: " + Thread.currentThread().getState().name());
try {Thread.sleep(1000);} catch (Exception e) {}
}
});
alfa.setName("Alfa thread");
System.out.println(alfa.getName() + " state before invoking .start() is: " + alfa.getState().name());
alfa.start();
int i = 0;
while (true) {
++i;
System.out.println(i + ". " + alfa.getName() + " state: " + alfa.getState().name());
System.out.println(i + ". " + alfa.getName() + " is interrupted?: " + alfa.isInterrupted());
Thread.sleep(1000);
}
}
}
演示,这个:
Alfa thread state before invoking .start() is: NEW
1. Alfa thread state: RUNNABLE
0. Alfa thread state: RUNNABLE
1. Alfa thread is interrupted?: false
1. Alfa thread state: RUNNABLE
2. Alfa thread state: TIMED_WAITING
2. Alfa thread is interrupted?: false
2. Alfa thread state: RUNNABLE
3. Alfa thread state: TIMED_WAITING
3. Alfa thread is interrupted?: false
4. Alfa thread state: TERMINATED //alfa is terminated!
4. Alfa thread is interrupted?: false //alfa is not interrupted. Seriously?
- 难道我没有得到什么,这是故意这样做的,因为它在幕后有一些想法吗?或者
- 只是一些东西,忘记正确实施了?
A Thread.State
of TERMINATED
表示指定的Thread
已经执行完毕。
终止的 Thread
不会被打断,您可能将两者混为一谈,它们是不同的。
isInterrupted()
方法 return 仅当线程已通过 interrupt()
方法被另一个线程中断时才为真。
看这里:
https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
线程终止并不意味着线程中断,因为它们是两个不同且独立的事物。
编辑:
我在评论中看到您对打断有点困惑,所以我想澄清一下。
所以,中断基本上是对线程的指示,它应该停止当前正在做的事情,并做其他事情。因此,中断的线程 不会停止或挂起 (因为您使用了恢复这个词),但它是一个应该停止正在做的事情的线程。例如,假设名为 myThread
的线程当前正忙于一项非常长的操作,如下所示:
public void reallyLongOperation() throws InterruptedException {
// the thread will stay in the loop for a long time
while(!taskFinished){
//stuff repeated for many cycles
if(Thread.interrupted()){
throw new InterruptedException("The really long operation has been interrupted");
}
}
}
现在,假设用户想要通过按下 GUI 上的按钮来取消这个非常长的操作。 AWT-EventQueue
线程调用 myThread.interrupt()
。现在 myThread
仍在循环中做事,但是当线程达到条件时,Thread.interrupted()
清除标志并且 return 为真,因为它已被中断。 InterruptedException
被抛出,我们必须像处理其他所有已检查的异常一样处理它。
现在,myThread.isInterrupted()
和 Thread.interrupted()
有什么区别?
如果中断标志为真,myThread.isInterrupted()
仅 return 为真。但是,它不会重置标志。
Thread.interrupted()
是一个静态方法,和前者一样 return 如果中断标志为真,则为真,但它也会清除它。
当一个Thread死掉,并且它从未被中断过,或者如果之前已经清除了标志,以上两种方法都会return false。
线程中断与线程状态无关,也与挂起无关。
当线程终止时 (Thread.State.TERMINATED
) 它仍然没有被中断。为什么?
我找到了 this, and I found this,但都没有回答我的问题。我已经在 OpenJDK 11 和 Oracle JDK 16 上试过了 - 没有区别,相同结果.
我已经使用 Java 10 多年了,多线程任务对我来说一直很清楚;然而,不小心,我遇到了一些奇怪的事情(对我来说),我很想知道。
我明白,private volatile boolean interrupted;
只是 class Thread
的标志(字段),我可以将其与 interrupt()
结合使用以便编码isInterrupted()
得到 true
.
但是,为什么 Thread.State.TERMINATED
state 不也创建相同的线程 interrupted
?
public class MainClass {
public static void main(String[] args) throws Exception {
Thread alfa = new Thread(() -> {
for (int i = 0; i < 3; i++) {
System.out.println(i + ". " + Thread.currentThread().getName() + " state: " + Thread.currentThread().getState().name());
try {Thread.sleep(1000);} catch (Exception e) {}
}
});
alfa.setName("Alfa thread");
System.out.println(alfa.getName() + " state before invoking .start() is: " + alfa.getState().name());
alfa.start();
int i = 0;
while (true) {
++i;
System.out.println(i + ". " + alfa.getName() + " state: " + alfa.getState().name());
System.out.println(i + ". " + alfa.getName() + " is interrupted?: " + alfa.isInterrupted());
Thread.sleep(1000);
}
}
}
演示,这个:
Alfa thread state before invoking .start() is: NEW
1. Alfa thread state: RUNNABLE
0. Alfa thread state: RUNNABLE
1. Alfa thread is interrupted?: false
1. Alfa thread state: RUNNABLE
2. Alfa thread state: TIMED_WAITING
2. Alfa thread is interrupted?: false
2. Alfa thread state: RUNNABLE
3. Alfa thread state: TIMED_WAITING
3. Alfa thread is interrupted?: false
4. Alfa thread state: TERMINATED //alfa is terminated!
4. Alfa thread is interrupted?: false //alfa is not interrupted. Seriously?
- 难道我没有得到什么,这是故意这样做的,因为它在幕后有一些想法吗?或者
- 只是一些东西,忘记正确实施了?
A Thread.State
of TERMINATED
表示指定的Thread
已经执行完毕。
终止的 Thread
不会被打断,您可能将两者混为一谈,它们是不同的。
isInterrupted()
方法 return 仅当线程已通过 interrupt()
方法被另一个线程中断时才为真。
看这里: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
线程终止并不意味着线程中断,因为它们是两个不同且独立的事物。
编辑:
我在评论中看到您对打断有点困惑,所以我想澄清一下。
所以,中断基本上是对线程的指示,它应该停止当前正在做的事情,并做其他事情。因此,中断的线程 不会停止或挂起 (因为您使用了恢复这个词),但它是一个应该停止正在做的事情的线程。例如,假设名为 myThread
的线程当前正忙于一项非常长的操作,如下所示:
public void reallyLongOperation() throws InterruptedException {
// the thread will stay in the loop for a long time
while(!taskFinished){
//stuff repeated for many cycles
if(Thread.interrupted()){
throw new InterruptedException("The really long operation has been interrupted");
}
}
}
现在,假设用户想要通过按下 GUI 上的按钮来取消这个非常长的操作。 AWT-EventQueue
线程调用 myThread.interrupt()
。现在 myThread
仍在循环中做事,但是当线程达到条件时,Thread.interrupted()
清除标志并且 return 为真,因为它已被中断。 InterruptedException
被抛出,我们必须像处理其他所有已检查的异常一样处理它。
现在,myThread.isInterrupted()
和 Thread.interrupted()
有什么区别?
-
如果中断标志为真,
myThread.isInterrupted()
仅 return 为真。但是,它不会重置标志。Thread.interrupted()
是一个静态方法,和前者一样 return 如果中断标志为真,则为真,但它也会清除它。
当一个Thread死掉,并且它从未被中断过,或者如果之前已经清除了标志,以上两种方法都会return false。
线程中断与线程状态无关,也与挂起无关。