2009-11-30 5 views
4

나는 블로킹 기능을 사용하여 프록시를 호출하고 무엇인가를주기를 기다리는 스레드를 실행 중이다.차단 작업을 기다리는 스레드를 중단 하시겠습니까?

나는 휘발성 부울과 중단의 알려진 패턴을 사용했습니다,하지만 난 그것을 작동합니다 확실하지 않다 :

Unreachable catch block for InterruptedException. This exception is never thrown from the try statement body

: 나는 InterruptedException에 대한 catch 블록을 추가하려고 할 때, 나는 오류

그래서 결코 InterruptedException을 얻지 못한다면 결코 차단 조치에서 벗어날 수 없으므로 결코 멈추지 않을 것입니다.

나는 약간 당황합니다. 어떤 생각?

public void run() {  
    Proxy proxy = ProxyFactory.generateProxy(); 
    Source source; 

    while (!isStopped) { 
     try { 
     source = proxy.getPendingSources(); 
     scheduleSource(source); 
     } catch (Exception e) { 
     log.error("UnExpected Exception caught while running",e); 
     } 
    } 
    } 

    public void stop() { 
    this.isStopped = true; 
    Thread.currentThread().interrupt(); 
    } 

답변

11

먼저 별도의 플래그가 필요하지 않습니다 (수행하는 경우 AtomicBoolean 사용). while 조건으로 Thread.currentThread().isInterrupted()을 확인하십시오.

둘째, 올바른 스레드가 중단되지 않으므로 중지 방법이 작동하지 않습니다. 다른 스레드가 stop을 호출하면 코드는 Thread.currentThread()을 사용합니다. 즉, 호출중인 스레드가 실행중인 스레드가 아닌 중단됩니다.

마지막으로 차단 방법은 무엇입니까? scheduleSource()입니까? 이 메서드가 InterruptedException을 throw하지 않으면 catch 할 수 없습니다.

는 다음과 같은 시도 :

private final AtomicReference<Thread> currentThread = new AtomicReference<Thread>(); 

public void run() { 
    Proxy proxy = ProxyFactory.generateProxy(); 
    Source source; 

    currentThread.set(Thread.currentThread()); 

    while (!Thread.currentThread().isInterrupted()) { 
     try { 
      source = proxy.getPendingSources(); 
      scheduleSource(source); 
     } catch (Exception e) { 
      log.error("UnExpected Exception caught while running", e); 
     } 
    } 
} 

public void stop() { 
    currentThread.get().interrupt(); 
} 
+0

고마워요! 나에게 몇 분이 걸렸지 만 나는 "Stop"에 대해 내가 잘못한 것을 깨달았다. 이 경우 스레드가 "중지"요청을 받으면 차단 조치 대기를 중지합니까? – Yossale

+0

아니면 휘발성 부울을 사용하여 중지 플래그를 표시하십시오. –

+1

@Tom scheduleSource() 또는 proxy.getPendingSources()가 차단 된 경우 어떻게됩니까? 나는 그 전화가 stop()에 의해 인터럽트되기를 원한다고 가정한다. – Kevin

1

어떻게 실행 스레드에서 stop을 (를) 호출 하시겠습니까?
다른 스레드에서 stop()을 호출하면 try/catch 블록에서 실행중인 스레드가 아니라 해당 스레드를 종료합니다.

2

당신 stop 방법은 잘못된 스레드에서 interrupt를 호출한다. Thread.currentThread()은 중단되지 않고 중단되지 않는 스레드입니다.

10

잘 정의 된 "차단 방법"중 일부만 인터럽트 할 수 있습니다. 스레드가 인터럽트되면 플래그가 설정되지만 스레드가 이러한 잘 정의 된 인터럽트 지점 중 하나에 도달 할 때까지는 아무 것도 발생하지 않습니다.

예를 들어, read()write()InterruptibleChannel으로 만든 스트림에서 호출되는 경우 호출이 중단 될 수 있습니다. Socket이 시작 지점으로 사용 된 경우 Thread에있는 interrupt()을 읽음으로 차단하면 아무 효과가 없습니다. 차단 I/O 작업이 성공적으로 중단되면 기본 채널이 닫힙니다.

또 다른 큰 클래스의 인터럽트 가능한 작업은 java.util.concurrent 패키지의 클래스에서 다양한 차단 작업에 의해 throw되는 작업입니다. 물론 원래의 wait() 메소드도 인터럽트 가능합니다.

블로킹 방법은 메소드 서명에서 throws InterruptedException을 찾아 식별 할 수 있습니다. 인터럽트의 부작용을 설명하기 위해 잘 문서화되어야합니다.

독자적으로 인터럽트 가능한 메서드를 작성할 수 있지만 인터럽트 가능한 하위 수준의 연산 자체로 구성되어야합니다.

+0

인터럽트 가능한 메소드를 작성하기 위해서는 주기적으로'Thread # interrupted()'를 테스트하고 달리 실행 시간이 긴 메소드 - 특히 루프를 포함하는 메소드 -에 InterruptedException을 던지기가 가능합니다. 루프 내에서 호출되는 메소드가 모두 인터럽트 할 수없는 경우에는 인터럽트를 자주 테스트하십시오. – seh

2

좋아, 사람들은 이것을 통해 나를 죽이지 마라.

재미있게 Thread.stop()을 실험하고, 차단 작업에서 스레드를 걷어 내고, ThreadDeath를 잡고, 대상 스레드를 활성 상태로 유지하고 계속 이동합니다.

작동하는 것 같습니다. 세상은 끝나지 않습니다. 그러나 나는 단지 말하고있다. 너는 너 자신에 대한 책임이있다. 왜 나는 랩을 할까?

관련 문제