你的位置:首页 > Java教程

[Java教程]使用Condition实现多线程之间调用(生产消费模式)


一,object 类的wait(),notify()和notifyAll()

Java 线程类也是一个object 类,它的实例都继承自java.lang.Thread 或其子类。
wait(),notify()和notifyAll()是Object类中的方法,常用于线程之间调度。

线程无数据运行可调用wait()让线程等待,不占用CUP资源,提高CPU有效的利用率。
例如,线程 B 可以等待线程 A 的一个信号,这个信号会通知线程 B 数据已经准备好了,B可以执行业务逻辑。

线程之间调度常应用于生产与消费模式下。

利用Object 对象的wait(),notify()和notifyAll()可以实现,但JDK1.5后有更好的替代方法。

二,Condition 类增强类


Condition 类,实现线程间的协作,相比使用Object的wait()、notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。因此通常来说比较推荐使用Condition。

Condition依赖于Lock接口,生成一个Condition的基本代码是lock.newCondition()
调用Condition的await()和signal()方法,必须在lock.lock()和lock.unlock之间才可以使用

 

三,Object与Conditon 对比

  Conditon中的await()对应Object的wait();
  Condition中的signal()对应Object的notify();
  Condition中的signalAll()对应Object的notifyAll()。

 

 四,使用Condition 实现生产消费

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Created by tank on 2016/11/22. * 使用Condition 实现线程间生产消费模式 */public class ConditionDemo {  Object[] queue = new Object[100];//队列  int readIndex = 0;//read索引位置  int writeIndex = 0;  int dataLen = 0;  final Lock lock = new ReentrantLock();  final Condition fullCondition = lock.newCondition();  final Condition emptyCondition = lock.newCondition();  public static void main(String[] args) {    final ConditionDemo demo = new ConditionDemo();    new Thread() {      @Override      public void run() {        for (int i = 0; i < 1000; i++) {          demo.write(i);        }      }    }.start();    new Thread() {      @Override      public void run() {        while (true) {          Object obj = demo.read();          if (obj != null) {            System.out.println((Integer) obj);          }        }      }    }.start();  }  //生产  public void write(Object obj) {    lock.lock();    try {      if (dataLen >= queue.length) {//队列写满了        System.out.println("队列写满了,等待.....");        fullCondition.await();        System.out.println("队列有空位了,唤醒.....");      }      queue[writeIndex] = obj;      writeIndex++;      dataLen++;      if (writeIndex >= queue.length) {        writeIndex = 0;      }      emptyCondition.signal();    } catch (InterruptedException e) {      e.printStackTrace();    } finally {      lock.unlock();    }  }  //消费  public Object read() {    lock.lock();    try {      if (dataLen <= 0) {        System.out.println("队列空了,等待数据.....");        emptyCondition.await();        System.out.println("队列有数据了,唤醒.....");      }      Object obj = queue[readIndex];      readIndex++;      dataLen--;      if (readIndex >= queue.length) {        readIndex = 0;      }      fullCondition.signal();      return obj;    } catch (InterruptedException e) {      e.printStackTrace();    } finally {      lock.unlock();    }    return null;  }}