zoukankan      html  css  js  c++  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;
        }
    }
  • 相关阅读:
    Xml命名空间添加前缀的意义
    解决vs Installer无法下载更新
    mongodb模糊查询
    mongodb排序
    mongodb如何修改_id
    向Mongodb中插入数组元素
    Mongodb 常见操作符
    452.用最少数量的箭引爆气球
    450.删除二叉搜索树中的节点-medium
    45.跳跃游戏 II
  • 原文地址:https://www.cnblogs.com/tankaixiong/p/6093779.html
Copyright © 2011-2022 走看看