Почему Thread.isInterrupted () всегда возвращает false? - PullRequest
20 голосов
/ 22 августа 2011

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

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

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

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

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

В определении темы:

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

вызов:

theThread.interrupt();

Ответы [ 4 ]

35 голосов
/ 22 августа 2011

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

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

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

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

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

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


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

16 голосов
/ 22 августа 2011

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

6 голосов
/ 22 августа 2011

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

public void run() {
    try {
        //Do something
    } catch (InterruptedException e) {
        // Do whatever local clean up you need to
        ...
        // Then let the owning Thread know it's been interrupted, so it too can clean up
        Thread.currentThread().interrupt(); // 
    }
}
1 голос
/ 22 августа 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...