zoukankan      html  css  js  c++  java
  • java 实现生产者-消费者模式

    生产和消费者模式有很多种,现在介绍几种常见的方式

    •   wait/notify实现生产和消费者模式

    1、使用wait/notify实现生产和消费者模式:

    public class Depot {
    
        // 实际容量
        private volatile int capacity = 0 ;
        // 最大容量
        private static final int MAX_CAPACITY = 100 ;
        //
        private final Object lock = new Object() ;
    
        public Depot(){
            
        }
    
        /**
         *  生产
         * @param: num
         * @return:
         */
        public void producer(int num) {
            if(num<0){
                System.out.println("生产数量不可为负数");
                throw new IllegalArgumentException("生产数量不可为负数") ;
            }
    
            synchronized (lock){
                // 生产
                int left = 0;
                try {
                    left = doProducer(num);
    
                    // 要求生产数量未达标,让出执行权
                    while (left > 0){
                        Thread.yield();
                        left = doProducer(left);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                lock.notify();
            }
    
        }
    
        /**
         *  实际生产逻辑
         * @param: num
         * @return: 返回未生产数量
         */
        private int doProducer(int num) throws InterruptedException {
            // 实际增加数量
            int grow = num ;
            // 未生产数量
            int left = 0 ;
    
            // 等待仓库被消费
            while (capacity>=MAX_CAPACITY){
                lock.wait();
            }
    
            // 计算实际新增数量
            if( (num+capacity) > MAX_CAPACITY ){
                grow = MAX_CAPACITY - capacity ;
                left = num - grow ;
            }
            capacity += grow ;
    
            // 仓库已经生产,通知消费者消费
            lock.notify();
            System.out.println(Thread.currentThread().getName() + " Plan Producer = " + num + " Actually = " + grow + " left =  " + left + "  capacity = " + capacity);
            return left ;
        }
    
        /**
         *  消费
         * @param: num
         * @return:
         */
        public void consumer(int num) {
            if(num<0){
                System.out.println("消费数量不可为负数");
                throw new IllegalArgumentException("消费数量不可为负数") ;
            }
    
            synchronized (lock){
                // 消费仓库
                int left = 0;
                try {
                    left = doConsumer(num);
    
                    // 要求消费数量未达标,让出执行权
                    while (left > 0){
                        Thread.yield();
                        left = doConsumer(left);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                // 仓库已经被消费,通知生产者生产
                lock.notify();
            }
    
        }
    
        /**
         *  实际消费逻辑
         * @param:   num
         * @return:  剩余未消费数量
         */
        private int doConsumer(int num) throws InterruptedException {
            // 实际消费数量
            int decrease = num ;
            // 剩余未消费
            int left = 0 ;
    
            // 等待仓库生产
            while (capacity <= 0){
                lock.wait();
            }
    
            // 计算实际消费数量
            if(decrease > capacity){
                decrease = capacity ;
                left = decrease - capacity ;
            }
            capacity -= decrease ;
    
            System.out.println(Thread.currentThread().getName() + " Plan Consumer = "+ num + " Actually = " + decrease + " left =  " + left + "  capacity = " + capacity );
            return left ;
        }
    
    }

    测试案例:

    public class ProducerAndConsumer {
        public static void main(String[] args) throws InterruptedException {
            Depot depot = new Depot() ;
    
            for(int x=0 ; x<4; x++){
                new Thread(new Runnable() {
                    @Override public void run() {
                        depot.producer(40);
                    }
                }).start();
            }
    
            Thread.sleep(2000L);
            for(int x=0 ; x<3; x++){
                new Thread(new Runnable() {
                    @Override public void run() {
                        depot.consumer(40);
                    }
                }).start();
            }
    
            Thread.sleep(2000L);
    
        }
    }

    运行结果:

    Thread-0 Plan Producer = 40 Actually = 40 left =  0  capacity = 40
    Thread-1 Plan Producer = 40 Actually = 40 left =  0  capacity = 80
    Thread-2 Plan Producer = 40 Actually = 20 left =  20  capacity = 100
    Thread-4 Plan Consumer = 40 Actually = 40 left =  0  capacity = 60
    Thread-2 Plan Producer = 20 Actually = 20 left =  0  capacity = 80
    Thread-3 Plan Producer = 40 Actually = 20 left =  20  capacity = 100
    Thread-6 Plan Consumer = 40 Actually = 40 left =  0  capacity = 60
    Thread-5 Plan Consumer = 40 Actually = 40 left =  0  capacity = 20
    Thread-3 Plan Producer = 20 Actually = 20 left =  0  capacity = 40

    其他待续.........

  • 相关阅读:
    Analog power pin UPF defination
    动态功耗计算
    静态功耗 计算
    Innovus 对multibit 的支持
    P &R 12
    P & R 11
    power-plan如何定
    P & R 10
    P & R 9
    线程基础
  • 原文地址:https://www.cnblogs.com/xiaoxing/p/8556236.html
Copyright © 2011-2022 走看看