JavaTM Platform
Standard Ed. 6

java.util.concurrent.locks
인터페이스 Condition

기존의 구현 클래스의 일람:
AbstractQueuedLongSynchronizer.ConditionObject , AbstractQueuedSynchronizer.ConditionObject


public interface Condition

Condition 는,Object 감시 메소드 (wait ,notify , 및 notifyAll )를 별개의 객체 로 분해해, 그것들에 임의 Lock 구현의 사용을 조합해, 객체 마다 복수의 대기 세트를 보관 유지하는 효과를 부여합니다. 여기서,Locksynchronized 메소드 및 문장의 사용을 옮겨놓아Condition 는 Object 감시 메소드의 사용을 옮겨놓습니다.

상태 ( 「상태 큐」나 「상태 변수」라고도 불린다)는, 어느 상태가 true 가 되었던 것(적)이 다른 thread에 의해 통지될 때까지, thread가 실행을 정지 (대기)하는 수단을 제공합니다. 이 공유 상태 정보에의 액세스는 다른 thread내에서 행해지기 (위해)때문에, 이 액세스를 보호할 필요가 있습니다. 이 때문에, 하등의 형식의 락이 이 상태와 관련지을 수 있고 있습니다. 상태 대기의 제공하는 주요 프로퍼티은,Object.wait 와 같이, 관련하는 락을 「원자적으로」해제해, 현재의 thread를 정지시키는 것입니다.

Condition 인스턴스는, 내재적으로 락에 바인드 되고 있습니다. 특정 Lock 용의 Condition 인스턴스를 취득하기 위해서, 인스턴스는 newCondition() 메소드를 사용합니다.

예로서puttake 메소드를 지원하는 바운드 버퍼를 보관 유지하는 경우를 생각합시다. 빈 상태(empty)의 버퍼에 대해서 take 가 시도되면(자), 항목이 이용 가능하게 될 때까지 thread가 블록 합니다. 가득한 상태의 버퍼에 대해서 put 가 시도되면(자), 공간이 이용 가능하게 될 때까지 thread가 블록 합니다. 버퍼내에서 항목 또는 공간이 이용 가능하게 된 시점에서 단일 thread 통지만의 최적화를 사용할 수 있도록(듯이),put thread와 take thread를 별개의 대기 세트내에서 대기시키기로 하겠습니다. 이것은, 2 개 Condition 인스턴스를 사용해 달성할 수 있습니다.

 class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }

   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0)
         notEmpty.await();
       Object x = items[takeptr];
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   }
 }
 
(이 기능은 ArrayBlockingQueue 클래스에 의해 제공되기 (위해)때문에, 이 사용 예의 클래스를 구현할 필요는 없다)

Condition 구현은, 통지 순서부가 보증되는 것이나, 통지의 실행시에 락을 보관 유지할 필요가 없는 것 등,Object 감시 메소드의 동작이나 시멘틱스와는 다른 동작이나 시멘틱스를 제공할 수 있습니다. 구현이 이러한 특수 시멘틱스를 제공하는 경우, 구현은 이러한 시멘틱스를 문서화할 필요가 있습니다.

Condition 인스턴스는 일반적으로의 객체이며, 그 자체를 synchronized 문의 타겟으로 사용할 수 있는 것, 및 독자적인 감시의대기통지 메소드를 호출할 수 있는 것에 유의해 주세요. Condition 인스턴스의 감시 락의 취득, 또는 그 감시 메소드의 사용은,Condition 에 관련지을 수 있었던 Lock 의 취득 또는대기 신호 송신 메소드의 사용과는 특히 관계가 없습니다. 혼란을 피하기 (위해)때문에, 독자 구현의 내부를 제외해,Condition 인스턴스를 이러한 방법에서는 결코 사용하지 않게 해 주세요.

특히 명기되어 있지 않은 한, 몇개의 파라미터에 대해 null 치를 건네주면(자),NullPointerException 가 throw 됩니다.

구현상의 고려사항

Condition 의 대기중에, 일반적으로, 기본으로 되는 플랫폼 시멘틱스에의 양보로서 「외관의 기동」이 허가됩니다. Condition 는 루프상에서 항상 대기해, 대기 대상 상태 예측을 테스트할 필요가 있기 (위해)때문에, 이것은 대부분의 응용 프로그램에서는 실질적인 효과는 거의 없습니다. 구현은 외관의 기동의 가능성을 자유롭게 삭제할 수 있습니다만, 어플리케이션 프로그래머는 그것이 발생해, 루프상에서 항상 대기하는 것과 상정하는 것을 추천합니다.

상태 대기의 3 개의 형식 (인터럽트가능, 인터럽트 불가, 및 시각 지정)에서는, 플랫폼에서의 구현의 용이성 및 퍼포먼스 특성이 다릅니다. 특히, 이러한 기능을 제공하면서, 순서부 보증등의 특정의 시멘틱스를 유지하는 것이 곤란한 경우가 있습니다. 게다가 실제의 thread 중단에 끼어드는 기능을 모든 플랫폼에서 구현하는 것은, 항상 실행 가능하다라고는 한정하지 않습니다.

따라서, 구현이, 3 개의 대기 형식 모두로 동일한 보증이나 시멘틱스를 정의하는 것은 요구되고 있지 않습니다. 또, 실제의 thread 중단에 대한 인터럽트를 지원할 필요도 없습니다.

구현은, 대기중의 각 메소드로 제공되는 시멘틱스나 보증, 및 구현이 thread 중단의 인터럽트를 지원해, 이 인터페이스로 정의된 인터럽트 시멘틱스에 따를 필요가 있는 경우를 명확하게 문서화할 필요가 있습니다.

일반적으로, 인터럽트는 취소를 의미해, 인터럽트의 체크는 빈번하게 행해지는 것은 아니기 때문에, 구현은 일반적으로의 메소드 복귀에 대한 인터럽트에 긍정적으로 응답할 수 있습니다. 이것은, 다른 액션이 thread를 블록 해제한 뒤에, 인터럽트가 발생했던 것(적)이 나타나는 경우에도 들어맞읍니다. 구현은, 이 동작을 문서화할 필요가 있습니다.

도입된 버젼:
1.5

메소드의 개요
 void await ()
          신호가 송신되는지,인터럽트가 발생할 때까지, 현재의 thread를 대기시킵니다.
 boolean await (long time, TimeUnit  unit)
          신호가 송신되는, 인터럽트가 발생한다, 또는 지정된 대기 시간이 경과할 때까지, 현재의 thread를 대기시킵니다.
 long awaitNanos (long nanosTimeout)
          신호가 송신되는, 인터럽트가 발생한다, 또는 지정된 대기 시간이 경과할 때까지, 현재의 thread를 대기시킵니다.
 void awaitUninterruptibly ()
          현재의 thread를, 신호가 보내질 때까지 대기시킵니다.
 boolean awaitUntil (Date  deadline)
          신호가 송신되는, 인터럽트가 발생한다, 또는 지정된 기한이 경과할 때까지, 현재의 thread를 대기시킵니다.
 void signal ()
          대기중의 thread를 1 개 기동합니다.
 void signalAll ()
          대기중의 모든 thread를 기동합니다.
 

메소드의 상세

await

void await()
           throws InterruptedException 
신호가 송신되는지,인터럽트가 발생할 때까지, 현재의 thread를 대기시킵니다.

Condition 에 관련지을 수 있고 있는 락은 원자적으로 해제됩니다. 또, 현재의 thread는 thread의 스케줄링으로서는 무효가 되어, 다음의 4 개중 한쪽이 일어날 때까지 대기합니다.

어느 경우에서도, 이 메소드가 현재의 thread를 돌려주기 전에, 이 상태에 관련지을 수 있었던 락을 재취득할 필요가 있습니다. thread의 복귀시에, 이 락을 보관 유지하는 것이 보증됩니다.

현재의 thread로,

InterruptedException 가 throw 되어 현재의 thread의 인터럽트 상태가 클리어 됩니다. 첫회시에는, 락이 해제되기 전에 인터럽트의 테스트가 실행될지 어떨지는 지정되지 않습니다.

구현상의 고려사항

이 메소드의 호출시에, 현재의 thread는, 이 Condition 에 관련지을 수 있고 있는 락을 보관 유지하는 것으로 간주해집니다. 이것이 응답 방법을 결정하는 요인이 될지 어떨지는, 구현에 따라서 다릅니다. 일반적으로, (IllegalMonitorStateException 등의) 예외가 throw 되어 구현은 그것을 문서화할 필요가 있습니다.

구현은, 신호에 응답해 실행되는 일반적으로의 메소드 복귀에 대한 인터럽트에 긍정적으로 응답할 수 있습니다. 이 경우, 구현은, 다른 대기 thread가 존재하는 경우에, 신호가 그 thread에 확실히 리다이렉트(redirect) 되도록(듯이) 할 필요가 있습니다.

예외:
InterruptedException - 현재의 thread로 인터럽트가 발생하는 ( 및 thread 중단의 인터럽트가 지원된다) 경우

awaitUninterruptibly

void awaitUninterruptibly()
현재의 thread를, 신호가 보내질 때까지 대기시킵니다.

이 상태에 관련지을 수 있고 있는 락은 원자적으로 해제됩니다. 또, 현재의 thread는 thread의 스케줄링으로서는 무효가 되어, 다음의 3 개중 한쪽이 일어날 때까지 대기합니다.

어느 경우에서도, 이 메소드가 현재의 thread를 돌려주기 전에, 이 상태에 관련지을 수 있었던 락을 재취득할 필요가 있습니다. thread의 복귀시에, 이 락을 보관 유지하는 것이 보증됩니다.

현재의 thread가 이 메소드에 들어갈 때 인터럽트 상태가 설정되는지, 대기중에인터럽트가 발생하는 경우, 신호가 송신될 때까지 대기가 계속됩니다. 이 메소드로부터의 최종 복귀시에도, 「인터럽트 상태」는 계속 설정됩니다.

구현상의 고려사항

이 메소드의 호출시에, 현재의 thread는, 이 Condition 에 관련지을 수 있고 있는 락을 보관 유지하는 것으로 간주해집니다. 이것이 응답 방법을 결정하는 요인이 될지 어떨지는, 구현에 따라서 다릅니다. 일반적으로, (IllegalMonitorStateException 등의) 예외가 throw 되어 구현은 그것을 문서화할 필요가 있습니다.


awaitNanos

long awaitNanos(long nanosTimeout)
                throws InterruptedException 
신호가 송신되는, 인터럽트가 발생한다, 또는 지정된 대기 시간이 경과할 때까지, 현재의 thread를 대기시킵니다.

이 상태에 관련지을 수 있고 있는 락은 원자적으로 해제됩니다. 또, 현재의 thread는 thread의 스케줄링으로서는 무효가 되어, 다음의 5 개중 한쪽이 일어날 때까지 대기합니다.

어느 경우에서도, 이 메소드가 현재의 thread를 돌려주기 전에, 이 상태에 관련지을 수 있었던 락을 재취득할 필요가 있습니다. thread의 복귀시에, 이 락을 보관 유지하는 것이 보증됩니다.

현재의 thread로,

InterruptedException 가 throw 되어 현재의 thread의 인터럽트 상태가 클리어 됩니다. 첫회시에는, 락이 해제되기 전에 인터럽트의 테스트가 실행될지 어떨지는 지정되지 않습니다.

이 메소드는, 복귀시에, 지정된 대기 시간을 나타내는 nanosTimeout 치에 대한 나머지의 추정 나노초수를 돌려줍니다. 타임 아웃 시간이 경과하고 있는 경우는, 제로 또는 제로 미만의 값을 돌려줍니다. 대기가 복귀해도 대기 상태가 여전히 보관 유지되지 않는 경우에, 이 값을 사용해, 재차 대기할지 어떨지, 및 그 기간을 결정할 수 있습니다. 일반적으로, 이 메소드는 다음의 형식이 됩니다.

synchronized boolean aMethod(long timeout, TimeUnit unit) {
long nanosTimeout = unit.toNanos(timeout);
while (! conditionBeingWaitedFor) {
if (nanosTimeout > 0)
nanosTimeout = theCondition.awaitNanos(nanosTimeout);
else
return false;
   }
   // ...
 }
 

설계상의 주의:이 메소드는, 남은 시간을 리포트할 때에 절약하고 에러의 발생을 피하기 위해서(때문에) 나노초의 인수를 지정할 필요가 있습니다. 이 정밀도가 저하하면(자), 대기 시간의 합계가, 지정된 재대기의 발생시보다 시스템적으로 짧지 않은 것을 프로그래머가 보증하는 것이 어려워집니다.

구현상의 고려사항

이 메소드의 호출시에, 현재의 thread는, 이 Condition 에 관련지을 수 있고 있는 락을 보관 유지하는 것으로 간주해집니다. 이것이 응답 방법을 결정하는 요인이 될지 어떨지는, 구현에 따라서 다릅니다. 일반적으로, (IllegalMonitorStateException 등의) 예외가 throw 되어 구현은 그것을 문서화할 필요가 있습니다.

구현은, 신호에 응답해 실행되는 일반적으로의 메소드 복귀에 대한 인터럽트, 또는 지정된 대기 시간의 경과 지시에 대한 인터럽트에 긍정적으로 응답할 수 있습니다. 어느 쪽의 경우도, 구현은, 다른 대기 thread가 존재하는 경우에, 신호가 그 thread에 확실히 리다이렉트(redirect) 되도록(듯이) 할 필요가 있습니다.

파라미터:
nanosTimeout - 나노초단위의 대기 시간
반환값:
이 메소드로부터 돌아올 때까지 대기하는 시간을 nanosTimeout 값으로부터 깎은 추정수. 정의 값은, 희망하는 시간만 대기할 수 있도록(듯이), 이 메소드의 이후의 호출에 대한 인수로서 사용된다. 제로 이하의 값은, 시간이 남지 않은 것을 나타낸다
예외:
InterruptedException - 현재의 thread로 인터럽트가 발생하는 ( 및 thread 중단의 인터럽트가 지원된다) 경우

await

boolean await(long time,
              TimeUnit  unit)
              throws InterruptedException 
신호가 송신되는, 인터럽트가 발생한다, 또는 지정된 대기 시간이 경과할 때까지, 현재의 thread를 대기시킵니다. 이 메소드의 동작은, 다음의 것과 동일해집니다.
awaitNanos(unit.toNanos(time)) > 0
 

파라미터:
time - 대기하는 최장 시간
unit - time 인수의 시간 단위
반환값:
메소드로부터의 복귀전에 대기 시간이 경과했던 것이 검출되었을 경우는 false, 그렇지 않은 경우는 true
예외:
InterruptedException - 현재의 thread로 인터럽트가 발생하는 ( 및 thread 중단의 인터럽트가 지원된다) 경우

awaitUntil

boolean awaitUntil(Date  deadline)
                   throws InterruptedException 
신호가 송신되는, 인터럽트가 발생한다, 또는 지정된 기한이 경과할 때까지, 현재의 thread를 대기시킵니다.

이 상태에 관련지을 수 있고 있는 락은 원자적으로 해제됩니다. 또, 현재의 thread는 thread의 스케줄링으로서는 무효가 되어, 다음의 5 개중 한쪽이 일어날 때까지 대기합니다.

어느 경우에서도, 이 메소드가 현재의 thread를 돌려주기 전에, 이 상태에 관련지을 수 있었던 락을 재취득할 필요가 있습니다. thread의 복귀시에, 이 락을 보관 유지하는 것이 보증됩니다.

현재의 thread로,

InterruptedException 가 throw 되어 현재의 thread의 인터럽트 상태가 클리어 됩니다. 첫회시에는, 락이 해제되기 전에 인터럽트의 테스트가 실행될지 어떨지는 지정되지 않습니다.

반환값은, 기한이 경과했는지의 여부를 나타냅니다. 이 값은 다음과 같이 사용할 수 있습니다.

synchronized boolean aMethod(Date deadline) {
boolean stillWaiting = true;
while (! conditionBeingWaitedFor) {
if (stillWaiting)
stillWaiting = theCondition.awaitUntil(deadline);
else
return false;
   }
   // ...
 }
 

구현상의 고려사항

이 메소드의 호출시에, 현재의 thread는, 이 Condition 에 관련지을 수 있고 있는 락을 보관 유지하는 것으로 간주해집니다. 이것이 응답 방법을 결정하는 요인이 될지 어떨지는, 구현에 따라서 다릅니다. 일반적으로, (IllegalMonitorStateException 등의) 예외가 throw 되어 구현은 그것을 문서화할 필요가 있습니다.

구현은, 신호에 응답해 실행되는 일반적으로의 메소드 복귀에 대한 인터럽트, 또는 지정된 기한의 경과 지시에 대한 인터럽트에 긍정적으로 응답할 수 있습니다. 어느 쪽의 경우도, 구현은, 다른 대기 thread가 존재하는 경우에, 신호가 그 thread에 확실히 리다이렉트(redirect) 되도록(듯이) 할 필요가 있습니다.

파라미터:
deadline - 대기하는 절대 시간
반환값:
복귀시에 기한이 경과하고 있는 경우는 false, 그렇지 않은 경우는 true
예외:
InterruptedException - 현재의 thread로 인터럽트가 발생하는 ( 및 thread 중단의 인터럽트가 지원된다) 경우

signal

void signal()
대기중의 thread를 1 개 기동합니다.

이 상태로 대기중의 thread가 존재하는 경우, 1 개의 thread가 기동용으로 선택됩니다. 이 thread는,await 로부터 복귀하기 전에 락을 재취득할 필요가 있습니다.


signalAll

void signalAll()
대기중의 모든 thread를 기동합니다.

이 상태로 대기중의 thread가 존재하는 경우, 모든 thread가 기동됩니다. 각 thread는,await 로부터 복귀하기 전에 락을 재취득할 필요가 있습니다.


JavaTM Platform
Standard Ed. 6

버그의 보고와 기능의 요청
한층 더 자세한 API 레퍼런스 및 개발자 문서에 대해서는,Java SE 개발자용 문서를 참조해 주세요. 개발자전용의 상세한 해설, 개념의 개요, 용어의 정의, 버그의 회피책, 및 코드 실례가 포함되어 있습니다.

Copyright 2006 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms . Documentation Redistribution Policy 도 참조해 주세요.