java并发包之Condition

1. 概括

  • Condition是java条件队列的实现,这就意味着Condition的强大之处在于它可以为多个线程间建立不同的Condition。
  • 作为一个多线程间协调通信的工具类,每个条件Contition对象内部维护了一个属于自己的等待队列,它使得某个或者某些线程一起等待某个条件(Condition ,只有当该条件具备( signal 或者 signalAll方法被带调用)时,这些等待线程才会被唤醒,从而重新争夺锁。

2. 实例

  • 以下是来自《并发编程实战》一书的例子,第一段代码是原始的synchronized+notify+条件谓词实现的条件队列,第二段代码使用java并发包的Condition + Lock。
//synchronized+notify实现的条件队列
public class BoundedBuffer extends BaseBoundedBuffer<V>{
    //条件谓词:not-full(通过父类的 !isFull()判断)
    //条件谓词:not-empty(通过父类的 !isEmpty()判断)

    public BoundedBuffer(int size){super(size)};

    //阻塞,直到not-full
    public synchronized void put(V v) throws InterruptedException{
         while(isFull()){
             wait(); //缓存区为满,一直阻塞
         }
         doPut(v); //向缓存区放入
         notifyAll();//唤醒被阻塞的线程
    }

    //阻塞,直到not-empty
    public synchronized V take(V v) throws InterruptedException{
         while(isEmpty()){
             wait(); //缓存区为空,一直阻塞
         }
         V v = doTake(); //从缓冲区取出
         notifyAll();//唤醒被阻塞的线程
         return v;
    }
}
//使用java并发包的Condition + Lock
public class BoundedBuffer<V>  extends BaseBoundedBuffer<V>{
   final Lock lock = new ReentrantLock();//锁对象
   final Condition notFull  = lock.newCondition();//写线程条件 
   final Condition notEmpty = lock.newCondition();//读线程条件 

   public void put(V v) throws InterruptedException {
     lock.lock();
     try {
       while (isFull())//如果队列满了 
         notFull.await();//阻塞写线程
       doPut(v); //向缓存区放入
       notEmpty.signal();//唤醒读线程
     } finally {
       lock.unlock();
     }
   }

   public V take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0)//如果队列为空
         notEmpty.await();//阻塞读线程
       V v = doTake();
       notFull.signal();//唤醒写线程
       return v;
     } finally {
       lock.unlock();
     }
   } 
 }
  • 对比两端代码,它们实现的功能其实是一样的,第二段代码结构更加清晰。

3. 总结

  • Condition 将 Object 监视器方法(wait、notify 和 notifyAll)根据条件的不同分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。与synchronized和Lock相比,Condition十分灵活,某些场景效率更高,适合多条件的讨论。

猜你喜欢

转载自blog.csdn.net/huanglu20125/article/details/79358889