zoukankan      html  css  js  c++  java
  • 基于ReentrantLock通知唤醒的生产消费模式

    生产者消费者

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class TaskExecutor {
        private List<Integer> list = new ArrayList<>();
        private AtomicInteger count = new AtomicInteger();
        private ReentrantLock lock = new ReentrantLock();
        /**
         * 积压消息容量
         */
        private int capacity;
        private Condition c1 = lock.newCondition();
        private Condition c2 = lock.newCondition();
    
        /**
         * 可读索引
         */
        private int read;
    
        public TaskExecutor(int capacity) {
            this.capacity = capacity;
        }
    
        public Integer product() {
            Integer value = null;
            lock.lock();
            try {
                while (list.size() >= capacity) {
                    c1.await();
                }
                value = count.incrementAndGet();
                list.add(value);
                read++;
                c2.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
    
            return value;
        }
    
        public Integer consume() {
            Integer value = null;
            lock.lock();
            try {
                while (list.size() <= 0) {
                    c2.await();
                }
                read--;
                value = list.remove(read);
    
                c1.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
    
            return value;
        }
    
        private Integer getSize() {
            lock.lock();
            try {
                return list.size();
            } finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            TaskExecutor taskExecutor = new TaskExecutor(20);
            new Thread(()-> {
                for (;;) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " 生产: " + taskExecutor.product() + " 积压: " + taskExecutor.getSize());
                }
            }, "producer").start();
            new Thread(()-> {
                for (;;) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " 消费: " + taskExecutor.consume() + " 积压: " + taskExecutor.getSize());
                }
            }, "consumer").start();
    
        }
    }
    
  • 相关阅读:
    eclipse打包
    java reflect 小例子
    linux查看java jdk安装路径和设置环境变量
    mapreduce (一) 物理图解+逻辑图解
    java url 解码 编码 奇怪的解码两次
    cygwin+hadoop+eclipse (三) 运行wordcount实例
    nutch 与 solr 的结合
    一个项目可以有多个源代码路径
    SHAppBarMessage
    记录系统开机启动登录注销等信息
  • 原文地址:https://www.cnblogs.com/snow-wolf-1/p/15156526.html
Copyright © 2011-2022 走看看