문제

나는 다음과 같은 장기적인 작업이 있습니다.

public void myCancellableTask() {
    while ( someCondition ) {
       checkIfCancelRequested();
       doSomeWork();
    }
 }

작업을 취소 할 수 있습니다 (취소가 요청되고 CheckIfCancelRequested ()가 취소 플래그를 확인합니다). 일반적으로 이와 같은 취소 가능한 루프를 작성할 때 플래그를 사용하여 취소가 요청되었음을 나타냅니다. 그러나 나는 또한 스레드를 사용할 수 있다는 것을 알고 있습니다. 나는 어떤 것이 선호되는 접근법인지, 왜 생각?

감사해요,

제프

도움이 되었습니까?

해결책

인터럽트는 지정된 대기 조건 목록에서 스레드를 폭파합니다. 자신의 취소 깃발은 그렇지 않습니다. IO와 이벤트에서 대기를 방해하려면 인터럽트를 사용하십시오. 그렇지 않으면 나만을 사용하십시오.

다른 팁

인터럽트 사용의 한 가지 문제는 그 것입니다 실행중인 모든 코드를 제어하지 않는 경우, 당신은 인터럽트가 "올바르게"작동하지 않을 위험이 있습니다. 인터럽트를 처리하는 방법에 대한 다른 사람의 이해가 깨진 이해 그들의 도서관에서. 그것이 API입니다 보이지 않게 처리 주위에 API를 내보내고 있습니다 interrupt당신이 의존하는 s.

당신의 예에서, 가정하십시오 doSomeWork 3 자 항아리에 있었고 다음과 같습니다.

public void doSomeWork() {
    try { 
        api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); }
}

이제 당신은 처리해야합니다 AssertionError (또는 당신이 사용하는 도서관이 던질 수있는 다른 것은 무엇이든). 경험이 풍부한 개발자가 인터럽트를받는 데 모든 종류의 넌센스를 던지는 것을 보았습니다! 반면에, 아마도 방법은 다음과 같이 보였을 것입니다.

public void doSomeWork() {
    while (true) {
        try { 
            return api.callAndWaitAnswer() ; 
        } 
        catch (InterruptedException e) { /* retry! */ }
    }
}

인터럽트 의이 "부적절한 취급"은 프로그램이 무기한으로 루프하게됩니다. 다시 말하지만, 이것을 말도 안되는 것으로 무시하지 마십시오. 차단 된 인터럽트 처리 메커니즘이 많이 있습니다.

적어도 자신의 깃발을 사용하면 3 자 라이브러리에는 완전히 보이지 않습니다.

그것은에 달려 있습니다 doSomeWork() 구현. 순수한 계산입니까, 아니면 (어느 시점에서) API (예 : IO) 호출을 차단하는 것이 포함됩니까? 당 Bmargulies 's 답변, JDK의 많은 차단 API는 중단 가능하며 스택에서 중단 된 예외를 전파합니다.

따라서 작업에 잠재적으로 차단 활동이 수반되면 인터럽트를 고려해야합니다. 설사 깃발을 사용하여 프로세스를 제어하기로 결정하고 인터럽트를 적절하게 잡아서 처리/전파해야합니다.

그 외에도 깃발에 의존하는 경우 깃발이 선언되었는지 확인하십시오. volatile 의미론.

나는 그것이 대부분의 경우 선호의 문제라고 생각합니다. 개인적으로 나는 손으로 만든 깃발을 먹을 것입니다. 예를 들어, 이렇게하면 스레드가 일관되지 않은 상태에 다른 물체를 남기지 않도록합니다. 게다가, 성능이 실제로 중요하다면, 예외를 사용하는 데 오버 헤드가 있음을 명심하십시오 (사례의 99%에서 무시할 수있는 경우에도).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top