博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Condition实现多线程之间调用(生产消费模式)
阅读量:6433 次
发布时间:2019-06-23

本文共 3132 字,大约阅读时间需要 10 分钟。

一,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; }}

 

转载地址:http://xzxga.baihongyu.com/

你可能感兴趣的文章
LINQ之路10:LINQ to SQL 和 Entity Framework(下)
查看>>
circle area
查看>>
怎么改变按钮的图标
查看>>
当输入流和输出流同时作用一个文件
查看>>
MySQL关于表碎片整理OPTIMIZE TABLE操作
查看>>
FortiGate 0458版本bug
查看>>
Java --- 多线程 面试题
查看>>
OA项目如何成功实施!
查看>>
FindMaxConsecutive.java
查看>>
面试官问:ZooKeeper 一致性协议 ZAB 原理
查看>>
DNS实现域名正解与反解
查看>>
Linux学习-标准输入输出
查看>>
CentOS 7 配置IP
查看>>
文本处理工具grep及正则表达式
查看>>
Intel VT-x处于禁用状态
查看>>
用什么软件可以修改PDF文件,软件的操作方法
查看>>
如何精简企业主数据“裹脚布”
查看>>
& 号和管道符号(|)在不同场景下的使用方法
查看>>
curl 浏览器模拟请求实战
查看>>
多个VLAN中的vrrp备份组配置举例
查看>>