당신 java.lang.Thread.interrupt()
은 호출했을 때 무엇을 설명 할 수 있습니까?
당신 java.lang.Thread.interrupt()
은 호출했을 때 무엇을 설명 할 수 있습니까?
답변:
Thread.interrupt()
대상 스레드의 중단 된 상태 / 플래그를 설정합니다. 그런 다음 해당 스레드에서 실행되는 코드는 중단 된 상태를 폴링하고 적절하게 처리 할 수 있습니다. 차단 된 일부 메소드 Object.wait()
는 중단 된 상태를 즉시 소비하고 적절한 예외를 발생시킬 수 있습니다 (일반적으로 InterruptedException
)
자바 중단은 선제 적이 지 않다. 인터럽트를 올바르게 처리하기 위해 두 스레드가 협력 해야하는 다른 방법을 사용하십시오. 대상 스레드가 인터럽트 된 상태를 폴링하지 않으면 인터럽트가 효과적으로 무시됩니다.
폴링 Thread.interrupted()
은 현재 스레드의 중단 된 상태를 리턴하고 해당 인터럽트 플래그를 지우는 메소드를 통해 발생합니다 . 일반적으로 스레드는 throw InterruptedException과 같은 작업을 수행 할 수 있습니다.
편집 (Thilo 주석에서) : 일부 API 메소드에는 인터럽트 처리 기능이 내장되어 있습니다. 내 머리 꼭대기에는 이것이 포함됩니다.
Object.wait()
, Thread.sleep()
및Thread.join()
java.util.concurrent
구조InterruptedException
) 대신을 사용 하지 않습니다 ClosedByInterruptException
.편집 ( @ thomas-pornin 의 답변에서 완전성에 대해 정확히 동일한 질문 에)
스레드 중단은 스레드를 조금씩 이동시키는 부드러운 방법입니다. 그것은 소총으로 실을 쏘는 것과는 대조적으로 실이 깨끗하게 빠져 나갈 기회를주는 데 사용됩니다 Thread.stop()
.
인터럽트 란?
인터럽트는 스레드가 수행중인 작업을 중지하고 다른 작업을 수행해야 함을 나타냅니다. 스레드가 인터럽트에 응답하는 방식을 정확하게 결정하는 것은 프로그래머의 책임이지만 스레드가 종료되는 것은 매우 일반적입니다.
어떻게 구현됩니까?
인터럽트 메커니즘은 인터럽트 상태로 알려진 내부 플래그를 사용하여 구현됩니다. 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
대상 스레드가 ( wait()
또는 호출 과 같이 본질적으로 동일한 일을하는 다른 관련 메소드를 호출 하여 sleep()
) 대기 중이면 중단됩니다. 즉, 대기중인 것을 기다리지 않고 대신 InterruptedException을 수신합니다.
wait()
이 상황에서 수행 할 작업을 결정하는 것은 스레드 자체 (라는 코드 )에 달려 있습니다. 스레드를 자동으로 종료하지 않습니다.
때때로 종료 플래그와 함께 사용됩니다. 스레드가 중단되면 스레드가이 플래그를 확인한 다음 자체 종료 할 수 있습니다. 그러나 다시, 이것은 단지 관습입니다.
완전성을 위해서, 다른 답변에 더하여, 스레드에 차단하기 전에 중단되는 경우 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;
}
}
Thread.interrupt()
대상 스레드의 인터럽트 상태 / 플래그를 true로 설정합니다.이를 사용하면 선택 Thread.interrupted()
하면 무한 스레드를 중지하는 데 도움이됩니다. http://www.yegor256.com/2015/10/20/interrupted-exception.html을 참조 하십시오
스레드 중단은 플래그 인터럽트 상태를 기반으로 합니다 . 모든 스레드에 대해 인터럽트 상태 의 기본값 은 false 로 설정됩니다 . 스레드에서 interrupt () 메소드가 호출 될 때마다 인터럽트 상태는 true 로 설정됩니다 .
공공 무효 인터럽트 ()
이 스레드를 중단시킵니다.
항상 허용되는 현재 스레드 자체가 중단되지 않는 한이 스레드의 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를 변경할 수없는 경우
인터럽트는 스레드가 수행중인 작업을 중지하고 다른 작업을 수행해야 함을 나타냅니다. 스레드가 인터럽트에 응답하는 방식을 정확하게 결정하는 것은 프로그래머에게 달려 있지만 스레드가 종료되는 것은 매우 일반적입니다. 아주 좋은 참조 : https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html