Что делает java.lang.Thread.interrupt()? - программирование

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

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

4b9b3361

Ответ 1

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

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

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

EDIT (из комментариев Тило): Некоторые методы API имеют встроенную обработку прерываний. Из верхней части моей головы это включает.

  • Object.wait()/Thread.sleep()
  • Большинство структур java.util.concurrent
  • Java NIO (но не java.io), и НЕ использует InterruptedException, вместо этого используя ClosedByInterruptException.

ИЗМЕНИТЬ (из @thomas-pornin ответ на точно такой же вопрос для полноты)

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

Ответ 2

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

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

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

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

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

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

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

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

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

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

Проверьте это для полного понимания того же:

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

Ответ 3

Если целевой поток ожидает (вызывая wait() или некоторые другие связанные методы, которые по сути делают то же самое, например sleep()), он будет прерван, что означает, что он перестает ждать, ожидая и получив InterruptedException.

Это полностью зависит от самого потока (код, который называется wait()), чтобы решить, что делать в этой ситуации. Это не автоматически завершает поток.

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

Ответ 4

Для полноты, в дополнение к другим ответам, , если поток прерывается до того, как он блокируется на Object.wait(..) или Thread.sleep(..) и т.д., это эквивалентно прерыванию сразу после блокировки этого метода, как показано в следующем примере.

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");
    }
}

Вывод:

$ 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

Вывод: если вы выполняете цикл следующим образом, а прерывание происходит в тот момент, когда элемент управления оставил Thread.sleep(..) и идет вокруг цикла, исключение все равно произойдет. Таким образом, совершенно безопасно полагаться на прерывание Exception, которое надежно выбрасывается после прерывания потока:

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

Ответ 5

Thread.interrupt() устанавливает прерванный статус/флаг целевого потока в значение true, которое при проверке с помощью Thread.interrupted() может помочь остановить бесконечный поток. См. http://www.yegor256.com/2015/10/20/interrupted-exception.html

Ответ 6

Прерывание потока основано на статусе прерывания флага . Для каждого значения по умолчанию для потока статуса прерывания установлено значение false. Всякий раз, когда в потоке вызывается метод прерывания(), для состояния прерывания установлено значение true.

  • Если статус прерывания = истина (прерывание() уже вызвано потоком) этот конкретный поток не может переспать. Если вызов вызывается в этом потоке, то прерывается исключение. После сброса исключения снова флаг установлен в значение false.
  • Если поток уже спал и вызывается прерывание(), поток выйдет из состояния сна и прервет прерывание Exception.

Ответ 7

public void interrupt()

Прерывает этот поток.

Если текущий поток не прерывает себя, что всегда разрешено, вызывается метод checkAccess этого потока, что может вызвать выброс SecurityException.

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

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

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

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

Прерывание потока, который не является живым, не нуждается в эффекте.

Броски:   SecurityException - если текущий поток не может изменить этот поток

Ответ 8

Прерывание является указанием на поток, который должен остановить то, что он делает, и сделать что-то еще. Это зависит от программиста, чтобы точно определить, как поток реагирует на прерывание, но очень часто заканчивается поток. Очень хороший референт: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Ответ 9

Метод Thread.interrupt() устанавливает внутренний флаг "статус прерывания". Обычно этот флаг проверяется методом Thread.interrupted().

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