스레드 인터럽트 메커니즘은 차단 대기에서 스레드를 깨우고 대상 스레드의 기존 처리 흐름을 방해하고 새로운 명령에 응답하는 방법을 제공합니다. Java는이 자유를 개발자에게 남겨두고 우리는 그것을 잘 활용해야합니다.
오늘 우리는 Java 스레드의 인터럽트 메커니즘에 대해 이야기 할 것입니다.
스레드 인터럽트 메커니즘은 두 가지 일반적인 용도를 갖는 방법을 제공합니다.
대기중인 차단에서 스레드를 깨우고 해당 "제어 인터럽트"처리를 만듭니다.
대상 스레드를 알리십시오. 기존 처리 흐름을 방해하고 새 명령에 응답하십시오.
첫 번째 목적을 예로 들어 다음 코드를 참조하십시오.
synchronized (lock) {try {while (! check ()) {lock.wait (1000); }} catch (InterruptedException e) {e.printstacktrace (); }}이 코드는 Java가 제공하는 대기/알림 메커니즘을 사용합니다. lock.wait ()의 스레드 실행이 차단됩니다. 실행할 스레드를 복원하는 세 가지 상황이 있습니다.
1. 시간 초과 1000ms 종료되고 다음 코드는 정상적으로 실행됩니다.
2. 다른 스레드는 다음 코드를 실행하여 적극적으로 깨어납니다.
동기화 (잠금) {lock.notifyall (); // 또는 lock.notify ();}이것은 또한 다음 코드를 정상적으로 실행합니다.
3. 기다려야하는 또 다른 스레드는 "인터럽트"입니다.
// 대기 스레드에 대한 참조를 가져옵니다. 스레드 a; a.interrupt ();
"인터럽트"인 스레드 A는 lock.wait ()에서 InterruptedException 예외를 던집니다.
요약하면, 당신은 Object.wait ()가 내부적으로 이러한 일을하고 있다고 생각할 수 있습니다.
부울 checktimeout = timeout> 0; 스레드 current = thread.currentThread (); lock.addwaiter (current); while (! current.isnotified ()) {if (current.isterrupted ()) {current.clearTerrupted (); 새로운 InterruptedException ()을 던지십시오. } if (checktimeout) {if (timeout == 0) break; 시간 초과-; }}대기는이 "바쁜 폴링"방법을 확인하기 위해 사용하지 않기 때문에 이것은 완전히 정확하지는 않지만 플래그 비트를 판단하는 논리가 정확하기 때문입니다.
위에서 언급 한 "수동으로 발행 된 인터럽트"작업부터 시작하겠습니다.
// sun.nio.ch.interruptiblePublic Interface Interprubible {void 인터럽트 (스레드 var1);} // java.lang.threadprivate 휘발성 인터럽트 블로커; 개인 객체 Blockerlock = new Object (); public void interprupt () {if (this! = thread.current ()) CheckAccess (); 동기화 된 (Blockerlock) {인터럽 가능한 b = 차단제; if (b! = null) {interrupt0 (); B. interrupt (this); 반품; }} interrupt0 ();} // 인터럽트를 설정하려면 기본 void interrupt0 ();Thread.interrupt ()의 첫 번째 판사 권한을 보인 다음 실제로 interrupt0 ()을 호출하여 스레드의 인터럽트 플래그를 설정하는 것을 볼 수 있습니다. 현재 스레드에 Nio의 인터럽트가 있으면 다시 호출됩니다.
인터럽트 0 ()은 스레드의 인터럽트 플래그를 설정합니다.
스레드가 차단되지 않고 Object.wait (), thread.join (), thread.sleep ()와 같은 Java 프로그램 로직에 의해 제어되지 않는 영역에 있지 않으면 어떻게됩니까? 대답은 아무 일도 일어나지 않을 것이며, 스레드가 중단되는지 여부는 인터럽트 플래그를 적극적으로 확인함으로써 만 알 수 있습니다.
확인하는 방법? 스레드는 두 개의 인터페이스, 스레드.
// java.lang.threadpublic static boolean interrupted () {return currentthread (). islerrupted (true);} public boolean is -interrupted () {return iSlerrupted (false);} 개인 기본 부울 isinterrupted (Boolean Clear -interrupted);둘 다 내부에 의존하는 것을 볼 수 있으며, 이는 스레드가 중단되었는지 여부를 반환하고 필요에 따라 인터럽트 플래그를 지우겠습니다.
함수 호출 블록이 있으면 Java 라이브러리 함수 표시가 차단 소스 서명에서 중단 예고를 던지 며 쓰기 시도 캐치가 인터럽트를 처리해야합니다.
위에서 언급했듯이 스레드가 차단되면 Java가 인터럽트 플래그를 확인하고 먼저 지우고 인터럽트 한 외출을 던집니다.
// java.lang.objectpublic final void void wait ()는 InterruptedException {wait (0);} 공개 최종 기본 무효 대기 (긴 타임 아웃) Drows InterruptedException;스레드가 InterruptedException을 수신 한 다음 차단을 던질 코드를 실행하면 "상관없이"처럼 계속 차단됩니다. Java가 내부적으로 인터럽트 플래그를 지우므로!
우리는 종종 InterruptedException을 처리하는 다음 세 가지 유형의 코드를 작성합니다.
처리를 위해 중단 예고를 상단 계층으로 처리하십시오.
public void foo ()는 interruptedException {synchronized (lock) {lock.wait (); }}InterruptedException 인터럽트 플래그 비트를 재설정합니다.
{synchronized (lock) {lock.wait (); }} catch (InterpruptedException e) {Thread.currentThread (). 인터럽트 (); //부서지다; }먼저 작업을 완료 한 다음 InterruptedException을 다시 던지십시오.
Public Void Bar ()는 InterruptedException {InterruptedException IE = NULL; 부울 완료 = 거짓; while (! done) {synchronized (lock) {try {lock.wait (); } catch (InterruptedException e) {ie = e; 계속하다; }} done = true; } if (예 : null) {throw IE; }}스레드가 인터럽트 플래그를 무시하고 InterruptedException을 무시하면 여전히 잘 작동합니다. 그러나 이것은 멀티 스레딩을 설계하려는 원래 의도와 상반됩니다. 우리는 스레드가 특정 기능을 달성하기 위해 조화롭게 순서대로 협력하기를 원하므로 제어 된 스레드는 인터럽트에 응답해야합니다. 그리고 우리는 Java가 개발자에게 남긴이 자유를 잘 활용해야합니다.
위의 내용은 이번에 소개 된 Java 스레드 인터럽트 메커니즘에 대한 모든 관련 지식입니다. 아무것도 이해하지 못하면 아래 메시지 영역에서 논의 할 수 있습니다. wulin.com을 지원 해주셔서 감사합니다.