java.util.concurrent.locks.Condition
- 하나의 락에 여러 조건으로 대기하게 할 수 있다. (예제 참고)
- 인터럽트에 반응하거나 반응하지 않은 대기 상태를 만들수 있다.
- 데드라인을 정해둔 대기 상태를 만들 수 있다.
package java.util.concurrent.locks;

import java.util.concurrent.*;
import java.util.Date;

public interface Condition {
    void await() throws InterruptedException;
    void awaitUninterruptibly();
    long awaitNanos(long nanosTimeout) throws InterruptedException;
    boolean await(long time, TimeUnit unit) throws InterruptedException;
    boolean awaitUntil(Date deadline) throws InterruptedException;
    void signal();
    void signalAll();
}

예제
java api 참조

Condition 객체를 활용하여 put(), take() 에 조건별로 나눠서 대기하기 때문에 siganlAll() 대신 더 효율적인 signal() 을 사용할 수 있게 되었다. 뭐 java api 내용을 보면 ArrayBlockingQueue 에서 이 기능을 하기 때문에 따로 구현하지 말라고 나오기는 함 ㅋㅋ
package study.lock.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class BoundedBuffer<T> {
 final Lock   lock   = new ReentrantLock();
 final Condition notFull  = lock.newCondition();
 final Condition notEmpty = lock.newCondition();
 final T[]   items   = (T[]) new Object[100];
 int tail, head, count;

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

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

참고
- java api
- java concurrency in practice
Posted by 짱가쟁이