• ReentrantLock_Condition_实现生产者消费者的疑问点


     之前的疑问点: 为什么用while不用if,同时也存在图片中疑问

    不懂结构还是很迷(待解答)

    /**
     * 生产者消费者
     * 重入锁&条件
     * 条件 - Condition, 为Lock增加条件。当条件满足时,做什么事情,如加锁或解锁。如等待或唤醒
     */
    package com.chenfan.base.server;
    
    import lombok.extern.slf4j.Slf4j;
    
    import java.util.LinkedList;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    @Slf4j
    public class TestContainer02<E> {
    
        private final LinkedList<E> list = new LinkedList<>();
        private final int MAX = 2;
    
        private Lock lock = new ReentrantLock();
        private Condition producer = lock.newCondition();
        private Condition consumer = lock.newCondition();
    
    
        public void put(E e) {
            lock.lock();
            log.info("进入 put " + Thread.currentThread().getName() + " 入锁");
            try {
                while (list.size() == MAX) {
                    log.info("lrwait" + Thread.currentThread().getName() + " 等待。。。");
                    // 进入等待队列。释放锁标记。
                    // 借助条件,进入的等待队列。
                    producer.await();
                }
                log.info("lrkaishi" + Thread.currentThread().getName() + " put 。。。");
                Thread.sleep(1000);
                list.add(e);
                // 借助条件,唤醒所有的消费者。
                consumer.signalAll();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            } finally {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                log.info("put 释放锁" + Thread.currentThread().getName());
                lock.unlock();
            }
        }
    
        public E get() {
            E e = null;
    
            lock.lock();
            //log.info("进入 get "+Thread.currentThread().getName() + " 入锁");
            try {
                while (list.size() == 0) {
                    log.info(Thread.currentThread().getName() + " 等待。。。");
                    // 借助条件,消费者进入等待队列
                    consumer.await();
                }
                log.info(Thread.currentThread().getName() + " get 。。。");
                Thread.sleep(1000);
    
                e = list.removeFirst();
                // 借助条件,唤醒所有的生产者
                producer.signalAll();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            } finally {
                lock.unlock();
            }
    
            return e;
        }
    
        public static void main(String[] args) throws InterruptedException {
            final TestContainer02<String> c = new TestContainer02<>();
            for (int i = 0; i < 4; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < 1; j++) {
                            log.info(c.get());
                        }
                    }
                }, "consumer" + i).start();
            }
    
    //        Thread.sleep(1000);
            for (int i = 0; i < 6; i++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int j = 0; j < 1; j++) {
                            c.put("container value " + j);
                        }
                    }
                }, "producer" + i).start();
            }
    
    
        }
    
    }
  • 相关阅读:
    第四章 分布式扩展
    第三章 2.性能压测,容量问题
    第三章 1.云部署,打包上传
    MySQL语法大全
    Python随手记
    Python操作Mysql中文乱码问题
    Python基础函数
    破解电信校园网路由限制
    ThinkPHP扩展函数的三个方法
    $_SERVERS预定义变量
  • 原文地址:https://www.cnblogs.com/liran123/p/12698045.html
Copyright © 2020-2023  润新知