zoukankan      html  css  js  c++  java
  • Lock的实现类ReentrantLock&Condition类的await/signal/signalAll(生产者消费者场景)

    jdk1.5之后

     java.util.concurrent.locks.Lock

    Lock接口

    方法:lock

       unlock

       newCondition

       tryLock

       tryLock(?)

       lockInterruptibly

    实现类:ReentrantLock

        ReadLock

        WriteLock

        (ReadLock和WriteLock是ReentrantReadWriteLock的静态内部类)


    详解ReentrantLock

     

        

    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @author DuanJiaPing
     * @date 2018/6/11 9:08
     *
     * 等待喚醒機制
     *
     * 生產者和消費者案例
     * 生產者生產的產品給店員,消費者從店員那獲取產品
     *
     * 使用lock同步锁
     * lock同步锁也有自己的线程等待和唤醒机制
     *
     * 通过Lock同步锁实现线程的通信,必须依赖Condition实例
     *
     * Condition
     * await()
     * signal()
     * signalALL()
     * Condition实例实质上被绑定到一个锁上
     * 为特定的Lock实例获得Condition实例,使用newCondition()方法
     *
     */
    public class TestProductorAndConsumer2 {
    
    
        public static void main(String[] args){
            Clerk2 clerk = new Clerk2();
            Productor2 productor = new Productor2(clerk);
            Consumer2 consumer = new Consumer2(clerk);
    
            new Thread(productor,"生产者A").start();
            new Thread(consumer,"消费者1").start();
            new Thread(productor,"生产者B").start();
            new Thread(consumer,"消费者2").start();
            new Thread(consumer,"消费者3").start();
            new Thread(consumer,"消费者4").start();
    
        }
    
    
    }
    
    /*
    * 店员类
    * 店员进货、售货,只有一个店员
    * */
    
    class Clerk2{
    
        /*库存*/
    
        private int product = 0;
    
        private Lock lock = new ReentrantLock();
    
        /*获取Condition实例*/
    
        Condition condition = lock.newCondition();
    
        /*
        * 此时,进货和售货的两个方法都操作共享数据product(库存)
        * 因此,这两个方法都存在线程安全问题
        * 解决:lock同步锁
        *
        * */
    
        /*
        * 进货
        * */
    
    
        public void get(){
    
            lock.lock();
            try{
                while (product >= 8) {
                    System.out.println("库存已满");
                    try{
                        condition.await();
                    }catch(Exception e){
    
                    }
                }
    
                System.out.println(Thread.currentThread().getName()+"--进货--当前库存--"+ ++product);
    
                condition.signalAll();
            }finally {
                lock.unlock();
            }
    
        }
    
        /*
        * 售货
        * */
    
        public void sale(){
            lock.lock();
            try{
                while(product <= 0){
                    System.out.println("库存不足");
                    try{
                        condition.await();
                    }catch(Exception e){
    
                    }
                }
    
                System.out.println(Thread.currentThread().getName()+"--售货--当前库存--"+ --product);
    
                condition.signalAll();
            }finally {
                lock.unlock();
            }
    
        }
    }
    
    class Productor2 implements Runnable{
        private Clerk2 clerk;
    
        public Productor2(Clerk2 clerk) {
            this.clerk = clerk;
        }
    
        @Override
        public void run() {
            //不断生产10个产品,提供给店员
    
            for(int i=1;i<=10;i++){
                clerk.get();
            }
        }
    }
    
    
    /*消费者类
    * 消费者从店员处购买产品
    * 多个消费者
    * 多线程*/
    
    class Consumer2 implements Runnable{
        private Clerk2 clerk;
    
        public Consumer2(Clerk2 clerk) {
            this.clerk = clerk;
        }
    
        @Override
        public void run() {
            try{
                Thread.sleep(200);
            }catch (Exception e){
    
            }
            for(int i=1;i<=5;i++){
                clerk.sale();
            }
    
        }
    }
  • 相关阅读:
    Java:Excel文件上传至后台
    JDK1.8中的HashMap实现
    Redis远程连接报错解决
    Redis操作命令总结
    HashMap实现原理及源码分析
    谈谈对Spring IOC的理解
    centos 7.3 服务器环境搭建——MySQL 安装和配置
    Linux系统下 docker安装命令
    JS求两个数组的交集 (假设数组已经经过排序)
    作用域和作用域链
  • 原文地址:https://www.cnblogs.com/duanjiapingjy/p/9432924.html
Copyright © 2011-2022 走看看