Различное поведение при вызове thread.isInterrupted и печать результата

Я немного запутался в поведении thread.isInterrupted в приведенной ниже программе.

public class ThreadPractice {

    public static void main(String args[]) throws InterruptedException {

        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("Starting thread..." + Thread.currentThread().getName());
                    Thread.sleep(10000);
                    System.out.println("Waking up");
                }catch(InterruptedException e){
                    System.out.println("Thread is interrupted!!!");
                    Thread.currentThread().interrupt();
                }
            }
        });

        t.start();
        Thread.sleep(2000);
        t.interrupt();
        //System.out.println(!t.isInterrupted());
        while(!t.isInterrupted()){
            System.out.println("Current thread not interrupted!!!");
        } 
    }
}

При выполнении вышеуказанной программы как таковой она печатает,

Starting thread...Thread-0
Thread is interrupted!!!

Но когда я раскомментирую оператор System.out для печати состояния прерывания, он запускается в бесконечную печать цикла "Текущий поток не прерывается"

Я не могу точно определить, что делает различие System.out.

Ответ 1

Обратите внимание, что я не всегда получаю бесконечный цикл.

Я подозреваю, что это связано с чередованием операций. Это помогает также проверить, жив ли поток:

System.out.println("Current thread not interrupted!!! Alive? " + t.isAlive());

Если поток не жив, его прерванный статус имеет значение false.

Я получаю вывод вроде:

Начальная нить... Тема-0
Тема прерывается!!! Текущая нить не прерывается!!! В живых? правда
Текущая нить не прерывается!!! В живых? ложь
[бесконечный цикл]

Я предполагаю, что первый цикл видит, что поток не прерывается, потому что InterruptedException удалил флаг, а затем reset флаг с interrupt() в методе run(), и поток может завершиться и не будет жив. больше.
Следующая проверка цикла видит, что она не жива, и вы начинаете бесконечный цикл.


Интересную вариацию можно получить, добавив:

System.out.println("Exiting Thread!!!");

В конце метода run() он обеспечивает задержку, достаточную для проверки состояния цикла между временем, в течение которого прерванный флаг равен reset, и времени, в течение которого поток умирает.

Ответ 2

В соответствии с Java-программой JVM завершается, как только все не-демона будут завершены.

Если вы не звонили t.interrupt(), дочерний поток будет активным. Итак, если вы проверяете while, то цикл t.isInterrupted() возвращает true. Итак, перерыв цикла.

Если вы вызываете t.interrupt() при выполнении этой операции, дочерний поток будет прерван. Итак, если вы проверяете while, то цикл t.isInterrupted() возвращает false. Потому что согласно Java Doc

Отключение потока игнорируется, потому что поток не был жив во время прерывания, будет отражен этим методом, возвращающим false.

while (true) { }

Итак, цикл никогда не прерывается.