java.lang.Thread.interrupt ()는 무엇을합니까?


답변:


250

Thread.interrupt()대상 스레드의 중단 된 상태 / 플래그를 설정합니다. 그런 다음 해당 스레드에서 실행되는 코드는 중단 된 상태를 폴링하고 적절하게 처리 할 수 ​​있습니다. 차단 된 일부 메소드 Object.wait()는 중단 된 상태를 즉시 소비하고 적절한 예외를 발생시킬 수 있습니다 (일반적으로 InterruptedException)

자바 중단은 선제 적이 지 않다. 인터럽트를 올바르게 처리하기 위해 두 스레드가 협력 해야하는 다른 방법을 사용하십시오. 대상 스레드가 인터럽트 된 상태를 폴링하지 않으면 인터럽트가 효과적으로 무시됩니다.

폴링 Thread.interrupted()은 현재 스레드의 중단 된 상태를 리턴하고 해당 인터럽트 플래그를 지우는 메소드를 통해 발생합니다 . 일반적으로 스레드는 throw InterruptedException과 같은 작업을 수행 할 수 있습니다.

편집 (Thilo 주석에서) : 일부 API 메소드에는 인터럽트 처리 기능이 내장되어 있습니다. 내 머리 꼭대기에는 이것이 포함됩니다.

  • Object.wait(), Thread.sleep()Thread.join()
  • 대부분의 java.util.concurrent구조
  • Java NIO (하지만 java.io는 아님 InterruptedException) 대신을 사용 하지 않습니다 ClosedByInterruptException.

편집 ( @ thomas-pornin 의 답변에서 완전성에 대해 정확히 동일한 질문 에)

스레드 중단은 스레드를 조금씩 이동시키는 부드러운 방법입니다. 그것은 소총으로 실을 쏘는 것과는 대조적으로 실이 깨끗하게 빠져 나갈 기회를주는 데 사용됩니다 Thread.stop().


22
sleep 또는 wait와 같은 메소드는 이러한 종류의 폴링을 수행하고 InterruptedException을 자체적으로 발생시킵니다.
Thilo

1
인터럽트 가능한 파일 I / O를 사용하는 경우 그 영향은 그리 크지 않습니다. 일반적으로 파일이 손상됩니다.
Marko Topolnik

Thread.interrupted를 언급하는 경우 Thread.isInterrupted 플래그도 있으며 플래그를 지우지 않으므로 일반적으로 응용 프로그램 개발자가 사용하기에 더 적합합니다.
Nathan Hughes 19

67

인터럽트 란?

인터럽트는 스레드가 수행중인 작업을 중지하고 다른 작업을 수행해야 함을 나타냅니다. 스레드가 인터럽트에 응답하는 방식을 정확하게 결정하는 것은 프로그래머의 책임이지만 스레드가 종료되는 것은 매우 일반적입니다.

어떻게 구현됩니까?

인터럽트 메커니즘은 인터럽트 상태로 알려진 내부 플래그를 사용하여 구현됩니다. Thread.interrupt를 호출하면이 플래그가 설정됩니다. 스레드가 정적 메소드 Thread.interrupted를 호출하여 인터럽트를 점검하면 인터럽트 상태가 지워집니다. 한 스레드에서 다른 스레드의 인터럽트 상태를 쿼리하는 데 사용되는 비 정적 Thread.isInterrupted는 인터럽트 상태 플래그를 변경하지 않습니다.

Thread.interrupt()API 에서 인용 :

이 스레드를 중단시킵니다. 먼저이 스레드의 checkAccess 메소드가 호출되어 SecurityException이 발생 될 수 있습니다.

이 스레드가 Object 클래스 또는 join (), join (long), join (long, int)의 wait (), wait (long) 또는 wait (long, int) 메소드 호출에서 차단 된 경우 이 클래스의, sleep (long) 또는 sleep (long, int) 메소드를 사용하면 인터럽트 상태가 지워지고 InterruptedException이 수신됩니다.

인터럽트 가능 채널에서이 스레드가 I / O 조작으로 차단되면 채널이 닫히고 스레드의 인터럽트 상태가 설정되며 스레드는 ClosedByInterruptException을 수신합니다.

이 스레드가 선택기에서 차단되면 스레드의 인터럽트 상태가 설정되고 선택기의 wakeup 메소드가 호출 된 것처럼 0이 아닌 값으로 선택 조작에서 즉시 리턴됩니다.

이전 조건 중 어느 것도 유지되지 않으면이 스레드의 인터럽트 상태가 설정됩니다.

이것에 대해 완전히 이해하려면 이것을 확인하십시오.

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


이것은 부분 설명에 따릅니다. 또한 인터럽트 가능한 메소드를 인터럽트합니다.
Lorne의 후작

@EJP이 질문은에 관한 것입니다. Thread.interrupt () 메소드는 무엇이고 어떻게 작동합니까? 링크로 게시 한 답변이 무엇인지 묻습니다. 나는 아직도 당신이 원하는 것을 이해하지 못합니까?
YoK

플래그로 구현되었다는 부분적으로 잘못된 진술을 정정하기를 바랍니다. 그것은 이야기의 일부일뿐입니다. 나에게는 분명해 보인다.
Lorne의 후작

@EJP 감사합니다. 나는 당신이 무슨 말을했는지 이해합니다. 내 답변을 업데이트하고 메소드에 대한 API 문서를 추가했습니다. 이것은 내 대답에서 빠진 인터럽트 가능한 메소드 부분을 다룹니다. 내 대답이 지금 완성 된 것처럼 보이기를 바랍니다 :).
YoK

13

대상 스레드가 ( wait()또는 호출 과 같이 본질적으로 동일한 일을하는 다른 관련 메소드를 호출 하여 sleep()) 대기 중이면 중단됩니다. 즉, 대기중인 것을 기다리지 않고 대신 InterruptedException을 수신합니다.

wait()이 상황에서 수행 할 작업을 결정하는 것은 스레드 자체 (라는 코드 )에 달려 있습니다. 스레드를 자동으로 종료하지 않습니다.

때때로 종료 플래그와 함께 사용됩니다. 스레드가 중단되면 스레드가이 플래그를 확인한 다음 자체 종료 할 수 있습니다. 그러나 다시, 이것은 단지 관습입니다.


9 살, 영원한 대답! +1
snr

10

완전성을 위해서, 다른 답변에 더하여, 스레드에 차단하기 전에 중단되는 경우 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(..)되고 루프를 돌고있는 순간에 인터럽트가 발생 하면 예외는 계속 발생합니다. 따라서 스레드가 중단 된 후 InterruptedException을 안정적으로 throw하는 것이 안전합니다 .

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


4

스레드 중단은 플래그 인터럽트 상태를 기반으로 합니다 . 모든 스레드에 대해 인터럽트 상태 의 기본값 은 false 로 설정됩니다 . 스레드에서 interrupt () 메소드가 호출 될 때마다 인터럽트 상태는 true 로 설정됩니다 .

  1. 인터럽트 상태 = true 인 경우 (interrupt ()가 이미 스레드에서 호출 된 경우) 해당 특정 스레드 가 휴면 상태가 될 수 없습니다 . 해당 스레드에서 휴면이 호출되면 인터럽트 된 예외가 발생합니다. 예외가 다시 발생하면 플래그가 false로 설정됩니다.
  2. 스레드가 이미 잠자고 인터럽트 () 가 호출되면 스레드는 잠자기 상태에서 벗어나 인터럽트 된 예외를 처리합니다.

1

공공 무효 인터럽트 ()

이 스레드를 중단시킵니다.

항상 허용되는 현재 스레드 자체가 중단되지 않는 한이 스레드의 checkAccess 메소드가 호출되어 SecurityException이 발생할 수 있습니다.

이 스레드가 Object 클래스 또는 join (), join (long), join (long, int)의 wait (), wait (long) 또는 wait (long, int) 메소드 호출에서 차단 된 경우 이 클래스의, sleep (long) 또는 sleep (long, int) 메소드를 사용하면 인터럽트 상태가 지워지고 InterruptedException이 수신됩니다.

인터럽트 가능 채널에서이 스레드가 I / O 조작으로 차단되면 채널이 닫히고 스레드의 인터럽트 상태가 설정되며 스레드는 ClosedByInterruptException을 수신합니다.

이 스레드가 선택기에서 차단되면 스레드의 인터럽트 상태가 설정되고 선택기의 wakeup 메소드가 호출 된 것처럼 0이 아닌 값으로 선택 조작에서 즉시 리턴됩니다.

이전 조건 중 어느 것도 유지되지 않으면이 스레드의 인터럽트 상태가 설정됩니다.

활성화되지 않은 스레드를 중단해도 아무런 영향이 없습니다.

SecurityException-현재의 thread가이 thread를 변경할 수없는 경우



1

Thread.interrupt () 메소드는 내부 '인터럽트 상태'플래그를 설정합니다. 일반적으로이 플래그는 Thread.interrupted () 메소드로 확인됩니다.

일반적으로 InterruptedException을 통해 존재하는 메소드는 인터럽트 상태 플래그를 지워야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.