Подтвердить что ты не робот

Почему Thread.isInterrupted() всегда возвращает false?

Я нашел метод JavaDoc:

Возвращает: true, если этот поток был прерван; false в противном случае.

Я думаю, что что-то не так с моим пониманием метода. Кроме того, я могу неправильно понять понятие "прерывание в потоке".

Любые объяснения приветствуются! Спасибо!

Фрагмент кода:

В определении потока:

public void run() {
        try {
            //Do something
        } catch (InterruptedException e) {
            System.out.println(isInterrupted());//Always false
            return;
        }
    }

Invoke:

theThread.interrupt();
4b9b3361

Ответ 1

Как только исключение будет сброшено, поток больше не находится в прерванном состоянии.

Ответ 2

Такое поведение обычно документируется в методах, которые вызывают это исключение. Например, javadoc для Object.wait() говорит:

"InterruptedException - если какой-либо поток прервал текущий поток до или в то время, когда текущий поток ожидал уведомления. Прерванный статус текущего потока очищается, когда это исключение выбрано.

Действительно, javadoc для самого исключения говорит следующее:

"Иногда метод может захотеть проверить, был ли прерван текущий поток, и если да, то немедленно выбросить это исключение. Для достижения этого эффекта можно использовать следующий код:

if (Thread.interrupted())  // Clears interrupted status!
     throw new InterruptedException();

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


Почему он работал так? Вы должны спросить дизайнеров, но я ожидаю, что они полагают, что обработчик исключений должен справиться с ситуацией, и поэтому нет необходимости устанавливать флаг в этой точке. (Если обработчик не полностью справится с ситуацией, он может либо перестроить исключение, либо вызвать Thread.getCurrentThread.interrupt(), чтобы снова установить флаг.)

Ответ 3

Добавляя к ответу cdhowie, один стандартный шаблон позволяет прерывать дескриптор потока. Это полезно с Executors, когда исполняемый код не "владеет" Thread и не должен мешать прерыванию (если вы действительно знать, что вы делаете)

public void run() {
    try {
        //Do something
    } catch (InterruptedException e) {
        // Do whatever local clean up you need to
        ...
        // Then let the owning Thread know it been interrupted, so it too can clean up
        Thread.currentThread().interrupt(); // 
    }
}

Ответ 4

Вы проверили бы isInterrupted() в своем собственном коде, например, из цикла. Если поток был прерван, вы можете затем прервать InterruptedException, чтобы прекратить выполнение.

В вашем примере, если вы поймали InterruptedException, вы можете быть уверены, что он был прерван, и вам не нужно проверять этот метод.