2010-08-03 2 views
19

이 대기 선언 갖는알림 또는 시간 초과를 위해 대기 (긴 시간 제한) 종료시 구별하는 방법은 무엇입니까?

public final native void wait(long timeout) throws InterruptedException; 

그것은 예외 : InterruptedException에 의해 종료하거나 시간 제한에 의해, 또는 때문에 /가는 notifyAll 메소드가 다른 스레드에서 호출 된 통지 수, 예외 잡기가 용이하지만 ...이

종료 원인이 시간 종료인지 알리는 방법은 무엇입니까?

편집 :

이것은 당신이 몇 가지 추가를 제공하지 않는 한 당신은 두 개의 구별 할 수 없다 (나는 그것을 좋아하지 않아 있지만), 일할 수있는 까다로운 방법

  long tBefore=System.currentTimeMillis(); 
      wait(TIMEOUT); 
      if ((System.currentTimeMillis() - tBefore) > TIMEOUT) 
      { 
       //timeout 
      } 
+2

나는 비슷한 필요성을 가지고 있었고 나의 경우에는 '세마포어'가 더 적합하다고 판명되었다. 'Semaphore.tryAcquire (long timeout, TimeUnit unit)'는 타임 아웃이 경과하면'false'를 반환합니다. – Santosh

+0

세마포어 공개 계약에 의해 지원되지 않는 대기 기능이 필요할 때까지 세마포어가 작동합니다. –

답변

7

입니다 암호. ThreadLocalnotify()

true로 설정되어 Boolean 그러나 먼저 확인해야합니다을 추가하여 예를 들어 로직이 차별화가 필요합니다.

+4

OP는 이미 예외가 발생하지 않을 것이며 시간 초과와 알림을 구분하려고합니다. 이것은 그 목적을 위해 유용한 정보를 제공하지 않습니다. –

+1

감사, 나는 OP를 오해. 지금 업데이트되었습니다. – Bozho

+0

다시 쓰려면 +1, 그렇다면 부울, 동기화 된 메서드는 지금 사용하고 있습니다. –

1

알림 및 시간 초과시 예외가 발생하지 않습니다.

Object.wait() 대신 java.lang.concurrent 패키지 동기화 개체를 사용하는 것이 더 좋습니다.

12

이 질문에 정확히 대답하지는 않지만 아마도 문제를 해결할 것입니다. 더 높은 수준의 동시성 메커니즘을 사용하십시오. Wait/Notify는 일반적으로 원하는 것보다 더 낮은 수준이므로 많은 다른 이유 중 하나입니다.

예를 들어 BlockingQueue.poll(long, TimeUnit)을 사용하는 경우 시간 초과 여부를 알기 위해 결과가 null인지 확인할 수 있습니다.

16

알림이 반환 할 수있는 또 다른 이유가 있습니다. 가짜 웨이크 업. 가짜 웨이크 업을 방지하는 것은 일부 하드웨어/OS 조합에서 매우 비쌉니다.

이 때문에 항상 루프에서 wait()를 호출하고 기다리고있는 조건을 다시 확인해야합니다. 이 작업을하는 동안 동시에 시간 초과를 확인하는 것이 쉽습니다.

자세한 내용은 "Java Concurrency In Practice"라는 책을 권합니다. 그리고 당신에게 맞는 모든 것을 얻을 수있는 더 높은 수준의 구조를 사용하십시오.

+0

+1 계좌에서 그러한 위조 된 웨이크 업을 갖습니다. –

2

을 직접 알 수있는 방법이 없습니다. 즉,이를 확인하기 위해 추가 코드를 추가해야합니다. 기다리는 경우(), 어떤 일이 일어날 때까지 기다리는 중입니다. 아마도 부울 변수를 설정하면됩니다. 이 경우 해당 변수의 상태를 확인하여 이벤트가 발생했는지 또는 시간 만 초과되었는지 확인할 수 있습니다. 또는 System.currentTimeMillis()의 값을 살펴보면 경과 시간이 제한 시간보다 크거나 같은지 확인할 수 있습니다. 그렇다면 시간 제한이 있다는 단서가됩니다 (절대 보장은 아니지만).). 또는 경과 시간이 시간 초과 기간보다 짧으면 확실히 시간 초과되지 않았습니다. 그게 도움이 되니?

+0

실제로 currentTimeMillis()를 사용하고 있습니다. 그러나 더 좋은 방법이 있는지 궁금합니다. –

+0

@ Hernán Eche 내 답변에 절대적인 보증이 아닙니다. 당신이 말할 수 있다면 왜 시간 초과 여부를 확인하고 싶습니까? 우리는 몇 가지 해결책을 찾을 수 있습니다. – YoK

+0

그래, 그게 아주 좋은 방법은 아니야, 나는 루프를 위해 그것을 사용하는 동안 (true) {wait (timeout); 다른 작업 ..; } 그래서 wait가 정말로 알려졌을 때 루프를 빠져 나갈 수 있습니다. 예를 들어 wait가 boolean을 반환하면 while (true) {if (wait (timeout)) break와 같은 것이됩니다. 다른 작업 ..; } 어쨌든 나는이 클래스의 모든 클래스를 캡슐화 할 것이고 동기화 된 메소드를 가진 플래그를 사용하여이 플래그의 설정과 동시에 대기/통지 할 것이다. –

3

System.currentTimeMillis()을 사용하지 마십시오. 대신 System.nanoTime()을 사용하십시오.

첫 번째는 절대 시간 (시스템 시계 기준)이며 시스템 시간이 변경되면 궁금한 결과가 발생할 수 있습니다. 예 : 시계가 한 시간 뒤로 이동하면 5 초 대기 시간이, 시계가 앞으로 움직이면 0 초 후에 10 분 대기가 수행됩니다.

두 번째 것은 상대 시간을 의미합니다. 항상 일정한 속도, 즉 에서 한 방향으로 실행되지만 원점은입니다. 즉, 값은 상대 시간을 측정하는 데만 사용할 수 있지만 날짜를 결정하는 데 사용할 수는 없으며 사용해서는 안됩니다.