• 用ReentrantLock和Condition实现生产者和消费者模式


    前面一篇文章《wait、notify应用场景(生产者-消费者模式)》是一种生产者消费者模式实现,今晚这是Lock方式实现,下面是源码:

    生产者代码:

    /**
     * 生产者
     *
     * @author monkjaver
     * @date 2018/12/18 22:10
     */
    public class Producer implements Runnable {
        /**
         * 产品容器
         */
        private List<Integer> container;
        private Lock lock;
        /**
         * 生产者条件
         */
        private Condition producerCondition;
        /**
         * 消费者条件
         */
        private Condition consumerCondition;
    
        public Producer(List<Integer> container, Lock lock, Condition producerCondition, Condition consumerCondition) {
            this.container = container;
            this.lock = lock;
            this.producerCondition = producerCondition;
            this.consumerCondition = consumerCondition;
        }
    
        public void produce() {
            //产品容器容量大小
            int capacity = 5;
            try {
                //获得锁
                lock.lock();
                //容器满了,不在生产
                if (container.size() == capacity) {
                    System.out.println("生产满了。。。。");
                    producerCondition.await();
                }
                Random random = new Random();
                int p = random.nextInt(50);
                //模拟1秒生产一个产品
                TimeUnit.MILLISECONDS.sleep(1000);
                System.out.println("生产产品:" + p);
                container.add(p);
                //生产一个产品,通知消费者
                consumerCondition.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //释放锁
                lock.unlock();
            }
    
        }
    
        @Override
        public void run() {
            while (true) {
                produce();
            }
        }
    }
    

      

    消费者代码:

    /**
     * @author monkjavaer
     * @date 2018/12/18 22:16
     */
    public class Consumer implements Runnable{
        /**
         * 产品容器
         */
        private List<Integer> container;
        private Lock lock;
        /**
         * 生产者条件
         */
        private Condition producerCondition;
        /**
         * 消费者条件
         */
        private Condition consumerCondition;
    
        public Consumer(List<Integer> container, Lock lock, Condition producerCondition, Condition consumerCondition) {
            this.container = container;
            this.lock = lock;
            this.producerCondition = producerCondition;
            this.consumerCondition = consumerCondition;
        }
    
        /**
         * 消费者消费产品
         */
        private void consume(){
            try {
                //获得锁
                lock.lock();
                //容器大小为null,不消费
                if (container.size() == 0) {
                    System.out.println("消费完了。。。。");
                    consumerCondition.await();
                }
                Integer p = container.remove(0);
                //模拟1秒消费一个产品
                TimeUnit.MILLISECONDS.sleep(1000);
                System.out.println("消费产品:" + p);
                //消费了,通知生产者
                producerCondition.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //释放锁
                lock.unlock();
            }
        }
        @Override
        public void run() {
            while (true){
               consume();
            }
        }
    }
    

      

    测试代码:

    public class ProducerConsumerTest {
        public static void main(String[] args) {
            List<Integer> container = new ArrayList<>();
            Lock lock = new ReentrantLock();
            Condition producerCondition = lock.newCondition();
            Condition consumerCondition = lock.newCondition();
            Thread producer = new Thread(new Producer(container,lock,producerCondition,consumerCondition));
            Thread consumer = new Thread(new Consumer(container,lock,producerCondition,consumerCondition));
            producer.start();
            consumer.start();
        }
    }
    

      

    ReentrantLock 公平锁和非公平锁

    非公平锁:获取锁的方式是抢占式的,随机的。默认ReentrantLock()是非公平的。jdk1.8源码如下:

    public ReentrantLock() {
    sync = new NonfairSync();
    }
    

      


    公平锁:线程获取锁的顺序是按照线程加锁的顺序来分配的。ReentrantLock(true)是公平的。jdk1.8源码如下:

    public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
    }
    

      

      

  • 相关阅读:
    HIVE Group by、join、distinct等实现原理
    【1.3】shell基础——调试shell(sh -x)
    sql server无法显示请求的对话框,检索数据失败
    sql server索引操作
    sql server中的alter
    tempdb无法收缩。使用 DBCC FREESYSTEMCACHE 解决
    在从该备份集进行读取时,RESTORE 检测到在数据库 "CISDB" 中的页(0:0)上存在错误。系统断定检查已失败
    【1.2】shell基础——stty erase解决按backspace出现^H的情况
    【1.1】shell基本实践——密码输入三次错误则结束
    (5.3.7)数据库迁移——sql server备份文件的加密解密
  • 原文地址:https://www.cnblogs.com/monkjavaer/p/10146679.html
Copyright © 2020-2023  润新知