isInterrupted () не запускается - PullRequest
3 голосов
/ 11 июля 2020

Экспериментируя с interrupt (), обнаружил, что isInterrupted () всегда ложно.

Другое дело, что замена isInterrupted () на Thread.interrupted () остановит поток.

Может ли кто-нибудь объяснить, почему происходит такое поведение?

public static void main(String[] args) {
        Thread counter = new Thread(new Worker());
        counter.start();
        counter.interrupt();
    }

    static class Worker extends Thread {

        @Override
        public void run() {
            String msg = "It was interrupted"; 

            while (true) {
                if (isInterrupted()) {
                    System.out.println(msg);
                    return;
                }
            }
        }
    }

Ответы [ 2 ]

6 голосов
/ 11 июля 2020

У вас есть два объекта потока: Worker - это отдельный поток, и вы заключаете его в новый отдельный объект Thread:

Thread counter = new Thread(new Worker());

Два объекта потока имеют два флага прерывания. Вызов counter.interrupt() устанавливает флаг прерывания во внешнем объекте потока, а вызов isInterrupted() проверяет флаг прерывания во внутреннем «рабочем» объекте потока.

Причина, по которой Thread.interrupted() останавливает поток, заключается в том, что он проверяет флаг прерывания текущего запущенного потока , который в данном случае будет внешним объектом.

Код будет более понятным, если вы избавитесь от объекта внешнего потока и напишете:

Worker counter = new Worker();
counter.start();
counter.interrupt();
3 голосов
/ 11 июля 2020

Вы должны инициализировать свой счетчик следующим образом:

 Thread counter = new Worker();

Поскольку Worker extends Thread передается как Runnable, у вас есть два разных экземпляра Thread.

Однако Thread.interrupted() прерывает текущий поток, поэтому он работает.

В качестве альтернативы вышеуказанному решению замените isInterrupted() на Thread.currentThread().isInterrupted().

...