Condition Variables JAVA多线程

线程这方面的学习一直不是很充分,今天在看张孝祥的视频的时候看到了一个3个线程轮流工作的例子,有一定的难度,最后运用了condition较方便的实现了。于是又搜索了一下相关资料,汇总如下:

Condition Variables
1. 就像上面反复强调的一样,wait-and-notify机制是与特定对象及其上的锁是绑定在一起的,锁和唤醒对象不能分开,这在某些情况下不是很方便;
2. JDK 1.5提供Condition接口来提供与其它系统几乎一致的condition variables机制;
3. Condition对象由Lock对象的newCondition()方法生成,从而允许一个锁产生多个条件变量,可以根据实际情况来等待不同条件;
4. 该书的例子没有什么特别的实际意义,但JDK 1.5文档中提供了一个例子,能充分说明使用Condition Variables使得程序更加清晰易读,也更有效率:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BufferTest{
 public static void main(String[] args){
  final BoundedBuffer bb = new BoundedBuffer();
 
  new Thread(){
   public void run(){
    try {
     for(int i=0;i<10;i++)
     bb.take();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }.start();

  try {
   for(int i=0;i<10;i++)
    bb.put(new Integer(1));
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}
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 != 0)
    notFull.await();
   items[putptr] = x;
   Thread.sleep(500);
   System.out.println("doPut");
   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];
   Thread.sleep(500);
   System.out.println("doTake");
   if (++takeptr == items.length)
    takeptr = 0;
   --count;
   notFull.signal();
   return x;
  } finally {
   lock.unlock();
  }
 }
}

具体的说明请参考JDK 1.5的文档。
5. 除了用lock和await-and-signal来代替synchronized和wait-and-notify外,其语义和机制基本一样。await()在进入前也会自动释放锁,然后再返回前重新获得锁;
6. 使用Condition Variables的原因:
  1) 如果使用Lock对象,则必须使用condition variables;
  2) 每个Lock对象可以创建多个condition variable.

猜你喜欢

转载自blog.csdn.net/frone/article/details/5026980