Вопрос-ответ

What does java.lang.Thread.interrupt() do?

Что делает java.lang.Thread.interrupt()?

Не могли бы вы объяснить, что java.lang.Thread.interrupt() делает при вызове?

Переведено автоматически
Ответ 1

Thread.interrupt() устанавливает состояние / флаг прерывания целевого потока. Затем код, запущенный в этом целевом потоке, МОЖЕТ опрашивать состояние прерывания и обрабатывать его соответствующим образом. Некоторые методы, которые блокируют, такие как Object.wait(), могут немедленно использовать состояние прервано и выдавать соответствующее исключение (обычно InterruptedException)

Прерывание в Java не является упреждающим. Другими словами, оба потока должны взаимодействовать, чтобы правильно обработать прерывание. Если целевой поток не опрашивает состояние прерывания, прерывание фактически игнорируется.

Опрос выполняется с помощью Thread.interrupted() метода, который возвращает состояние прерванного текущего потока И снимает этот флаг прерывания. Обычно поток может затем выполнить что-то вроде исключения InterruptedException .

ПРАВКА (из комментариев Thilo): В некоторые методы API встроена обработка прерываний. На мой взгляд, это включает в себя.


  • Object.wait(), Thread.sleep() и Thread.join()

  • Большинство java.util.concurrent структур

  • Java NIO (но не java.io) и он НЕ использует InterruptedException, вместо этого используя ClosedByInterruptException.

РЕДАКТИРОВАТЬ (из ответа @thomas-pornin на точно такой же вопрос для полноты картины)

Прерывание потока - это щадящий способ подтолкнуть поток. Это используется, чтобы дать потокам возможность чисто завершить работу, в отличие от Thread.stop() того, что больше похоже на стрельбу по потоку из штурмовой винтовки.

Ответ 2

Что такое прерывание ?


Прерывание - это указание потоку, что он должен прекратить то, что делает, и заняться чем-то другим. Программисту решать, как именно поток реагирует на прерывание, но очень часто поток завершается.


Как это реализовано ?


Механизм прерывания реализован с использованием внутреннего флага, известного как состояние прерывания. Вызов Thread.interrupt устанавливает этот флаг. Когда поток проверяет наличие прерывания путем вызова статического метода Thread.interrupted , состояние прерывания очищается. Нестатический поток.isInterrupted, который используется одним потоком для запроса состояния прерывания другого, не изменяет флаг состояния прерывания.


Цитата из Thread.interrupt() API:


Прерывает этот поток. Сначала вызывается метод checkAccess этого потока, который может вызвать исключение SecurityException .


Если этот поток заблокирован при вызове методов wait(), wait(long) или wait(long, int) класса Object или методов join(), join(long), join(long, int), sleep(long) или sleep(long, int) этого класса, то его состояние прерывания будет очищено и он получит исключение InterruptedException .


Если этот поток заблокирован в операции ввода-вывода на прерываемом канале, то канал будет закрыт, будет установлено состояние прерывания потока, и поток получит исключение ClosedByInterruptException .


Если этот поток заблокирован в селекторе, то будет установлено состояние прерывания потока, и он немедленно вернется из операции выбора, возможно, с ненулевым значением, точно так же, как если бы был вызван метод пробуждения селектора.


Если ни одно из предыдущих условий не выполняется, то для этого потока будет установлено состояние прерывания.


Проверьте это, чтобы получить полное представление о том же :

http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Ответ 3

If the targeted thread has been waiting (by calling wait(), or some other related methods that essentially do the same thing, such as sleep()), it will be interrupted, meaning that it stops waiting for what it was waiting for and receives an InterruptedException instead.

It is completely up to the thread itself (the code that called wait()) to decide what to do in this situation. It does not automatically terminate the thread.

It is sometimes used in combination with a termination flag. When interrupted, the thread could check this flag, and then shut itself down. But again, this is just a convention.

Ответ 4

For completeness, in addition to the other answers, if the thread is interrupted before it blocks on Object.wait(..) or Thread.sleep(..) etc., this is equivalent to it being interrupted immediately upon blocking on that method, as the following example shows.

public class InterruptTest {
public static void main(String[] args) {

Thread.currentThread().interrupt();

printInterrupted(1);

Object o = new Object();
try {
synchronized (o) {
printInterrupted(2);
System.out.printf("A Time %d\n", System.currentTimeMillis());
o.wait(100);
System.out.printf("B Time %d\n", System.currentTimeMillis());
}
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("C Time %d\n", System.currentTimeMillis());

printInterrupted(3);

Thread.currentThread().interrupt();

printInterrupted(4);

try {
System.out.printf("D Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("E Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("F Time %d\n", System.currentTimeMillis());

printInterrupted(5);

try {
System.out.printf("G Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("H Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("I Time %d\n", System.currentTimeMillis());

}
static void printInterrupted(int n) {
System.out.printf("(%d) Am I interrupted? %s\n", n,
Thread.currentThread().isInterrupted() ? "Yes" : "No");
}
}

Output:

$ javac InterruptTest.java 

$ java -classpath "." InterruptTest
(1) Am I interrupted? Yes
(2) Am I interrupted? Yes
A Time 1399207408543
WAS interrupted
C Time 1399207408543
(3) Am I interrupted? No
(4) Am I interrupted? Yes
D Time 1399207408544
WAS interrupted
F Time 1399207408544
(5) Am I interrupted? No
G Time 1399207408545
H Time 1399207408668
I Time 1399207408669

Implication: if you loop like the following, and the interrupt occurs at the exact moment when control has left Thread.sleep(..) and is going around the loop, the exception is still going to occur. So it is perfectly safe to rely on the InterruptedException being reliably thrown after the thread has been interrupted:

while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
break;
}
}
java multithreading