When thread gets terminated (Thread.State.TERMINATED
) it is still not interrupted. Why?
I found this, and I found this, but neither answers my question.I have tried this out on OpenJDK 11 and Oracle JDK 16 – no difference, same result.
I have been working with Java for more than 10 years now, and multithreading tasks have always been clear to me; yet, accidentally, I’ve encountered something strange (to me), which I’m wondering about.
I understand, that private volatile boolean interrupted;
is just a flag (field) of class Thread
, which I could make use in conjunction with interrupt()
in order to code some logic up with the case when isInterrupted()
gets true
.
However, why does Thread.State.TERMINATED
state doesn’t also make the same thread 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); } } }
demonstrates, this:
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?
- Am I not getting something and this is purposefully done so, as it has some idea behind the scenes? or
- It is just something, that has been forgotten to be implemented correctly?
Advertisement
Answer
A Thread.State
of TERMINATED
means that the specified Thread
has completed execution.
A terminated Thread
is not interrupted, you’re probably mixing the two things, which are different.
The isInterrupted()
method returns true only if the thread has been interrupted by another thread via the interrupt()
method.
Take a look here: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Thread termination does not imply thread interruption, because they are two different and independent things.
Edit:
I’ve seen in the comments that you have a bit of confusion with the interruption, so I wanted to clarify it.
So, basically an interrupt is an indication to a thread, that it should stop what’s currently doing, and do something else. So, an interrupted thread is not stopped or suspended (since you used the word resume), but it is a thread that should stop what’s doing. For example let’s say that a thread named myThread
is currently busy on a really long operation, like this:
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"); } } }
Now, let’s say the user wants to cancel this really long operation by pressing a button on the GUI. The AWT-EventQueue
thread calls myThread.interrupt()
. Now myThread
is still doing stuff in the cycle, but when the thread reaches the condition, Thread.interrupted()
clears the flag and returns true, since it has been interrupted. InterruptedException
is thrown, and we have to handle it like every other checked exception.
Now, what’s the difference between myThread.isInterrupted()
and Thread.interrupted()
?
myThread.isInterrupted()
only returns true if the interrupted flag is true. Though, it does not reset the flag.Thread.interrupted()
is a static method, and like the former returns true if the interrupted flag is true, but it also clears it.
When a Thread dies, and it has never been interrupted, or if the flag has been cleared before, both the methods above will return false.
Thread interruption has nothing to do with thread’s status, nor with suspension.