답변:
이것은 상태 를 유지 하기 위해 수행됩니다 .
당신이 InterruptException
그것을 잡아 삼킬 때, 당신은 본질적으로 더 높은 수준의 메소드 / 스레드 그룹이 인터럽트를 알지 못하게합니다. 문제가 발생할 수 있습니다.
를 호출 Thread.currentThread().interrupt()
하면 스레드의 인터럽트 플래그를 설정하므로 높은 수준의 인터럽트 핸들러가이를 감지하여 적절하게 처리 할 수 있습니다.
실제로 Java Concurrency는 이에 대한 자세한 내용은 7.1.3 장 : 인터럽트에 응답 에서 설명합니다 . 규칙은 다음과 같습니다.
스레드의 중단 정책을 구현하는 코드 만이 중단 요청을 삼킬 수 있습니다. 범용 작업 및 라이브러리 코드는 중단 요청을 삼켜서는 안됩니다.
interrupt()
는 호출이 중단 된 플래그 를 설정 하는 유일한 방법 이라는 점에 주목할 필요가 InterruptedException
있습니다.
이 코드 샘플은 약간 명확하다고 생각합니다. 작업을 수행하는 클래스 :
public class InterruptedSleepingThread extends Thread {
@Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i=0;i<Integer.MAX_VALUE;i++) {
//You are kidding me
System.out.println(i + " " + i*2);
//Let me sleep <evil grin>
if(Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
}else {
sleepBabySleep();
}
}
}
/**
*
*/
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
메인 클래스 :
public class InterruptedSleepingThreadMain {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
InterruptedSleepingThread thread = new InterruptedSleepingThread();
thread.start();
//Giving 10 seconds to finish the job.
Thread.sleep(10000);
//Let me interrupt
thread.interrupt();
}
}
상태를 다시 설정하지 않고 인터럽트 호출을 시도하십시오.
노트 :
오랜 시간 동안 대기하는 스레드를 어떻게 중지합니까 (예 : 입력)?
이 기술이 작동하려면 인터럽트 예외를 포착하고 처리 할 준비가되지 않은 메소드가 즉시 예외를 재확인하는 것이 중요합니다. 우리는 예외를 다시 던지는 것이 항상 가능한 것은 아니기 때문에 다시 던지기보다는 재 검증을 말합니다. InterruptedException을 잡는 메소드가이 (확인 된) 예외를 발생 시키도록 선언되지 않은 경우, 다음과 같은 incantation으로 "자체를 다시 인터럽트"해야합니다.
Thread.currentThread().interrupt();
이를 통해 스레드는 가능한 한 빨리 InterruptedException을 다시 발생시킵니다.
나는 그것이 나쁜 습관이거나 적어도 약간 위험하다고 생각합니다. 일반적으로 높은 수준의 방법은 차단 작업을 수행하지 않으며 InterruptedException
거기서 보지 않습니다 . 인터럽트 가능한 작업을 수행하는 모든 장소에서 마스크를 숨기면 절대 얻을 수 없습니다.
Thread.currentThread.interrupt()
다른 예외 또는 시그널링 인터럽트 요청을 다른 방식으로 제기하지 않는 유일한 이론적 근거 (예 : interrupted
스레드의 메인 루프에서 로컬 변수 변수 설정 )는 finally
블록 과 같이 예외로 실제로 아무것도 할 수없는 상황 입니다.
Thread.currentThread.interrupt()
전화의 의미를 더 잘 이해하려면 Péter Török의 답변을 참조하십시오 .
자바 문서에서 참조
이 스레드가 wait (), join (), sleep (long) 호출에서 차단되면 인터럽트 상태가 지워지고 InterruptedException이 수신됩니다.
이 스레드가 I / O 작업에서 차단되면 스레드의 인터럽트 상태가 설정되고 스레드는 ClosedByInterruptException을 수신합니다.
이 스레드가 선택기에서 차단되면 스레드의 인터럽트 상태가 설정되고 선택 작업에서 즉시 반환됩니다.
이전 조건 중 어느 것도 유지되지 않으면이 스레드의 인터럽트 상태가 설정됩니다.
따라서 @Ajay George Answer의 sleepBabySleep () 메소드를 I / O 작업 또는 sysout으로 변경하면 프로그램을 중지하기 위해 상태를 다시 설정할 필요가 없습니다. (BTW, 그들은 심지어 InterruptedException을 던지지 않습니다)
@ Péter Török이 말한 것처럼 => 상태를 유지하기 위해 수행됩니다. (특히 InterruptedException을 발생시키는 메소드)
InterruptedException
투명 도료 상태를 중단 이 그렇게 할 때. 나는이 관점에서 답변을 명확하게 생각 하는 이유 는 인터럽트 상태를 유지해야합니다.