zoukankan      html  css  js  c++  java
  • 关于生产者与消费者模式的两种实现方式

    1、wait & notify 方法:

    public class WaitAndNotify {
        private final int MAX_SIZE = 100;
        private LinkedList<Object> list = new LinkedList<Object>();
    
        public void produce(int num)
        {
            synchronized (list)
            {
                while (list.size() + num > MAX_SIZE)
                {
                    System.out.println("要生产的产品数:" + num + ", 现库存量为:"
                            + list.size() + " 不能继续生产!");
                    try
                    {
                        list.wait();
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
    
                for (int i = 1; i <= num; ++i)
                {
                    list.add(new Object());
                    System.out.println("已生产产品数:" + num + ", 现产品量为:" + list.size());
                }
                list.notifyAll();
            }
        }
    
        public void consume(int num)
        {
            synchronized (list)
            {
                while (list.size() < num)
                {
                    System.out.println("要消费的产品量:" + num + ", 现库存量为:"
                            + list.size() + ",存量不足,暂时不能消费!");
                    try
                    {
                        list.wait();
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
    
                for (int i = 1; i <= num; ++i)
                {
                    list.remove();
                    System.out.println("已消费产品数" + num + ", 现存量为:" + list.size());
                }
                list.notifyAll();
            }
        }
    }
    
    public class Producer implements Runnable{
        private int num;
        private WaitAndNotify storage;
    
        public Producer(WaitAndNotify storage)
        {
            this.storage = storage;
        }
    
        public void run()
        {
            produce(num);
        }
    
        public void produce(int num)
        {
            storage.produce(num);
        }
    
        public int getNum()
        {
            return num;
        }
    
        public void setNum(int num)
        {
            this.num = num;
        }
    
        public WaitAndNotify getStorage()
        {
            return storage;
        }
    
        public void setStorage(WaitAndNotify storage)
        {
            this.storage = storage;
        }
    }
    
    public class Consumer implements Runnable{
        private int num;
        private WaitAndNotify storage;
    
        public Consumer(WaitAndNotify storage)
        {
            this.storage = storage;
        }
    
        public void run()
        {
            consume(num);
        }
    
        public void consume(int num)
        {
            storage.consume(num);
        }
    
        public int getNum()
        {
            return num;
        }
    
        public void setNum(int num)
        {
            this.num = num;
        }
    
        public WaitAndNotify getStorage()
        {
            return storage;
        }
    
        public void setStorage(WaitAndNotify storage)
        {
            this.storage = storage;
        }
    }
    
    public class WaitAndNotifyTest {
        public static void main(String[] args) {
            WaitAndNotify storage = new WaitAndNotify();
    
            Producer p1 = new Producer(storage);
            Producer p2 = new Producer(storage);
            Producer p3 = new Producer(storage);
            p1.setNum(10);
            p2.setNum(20);
            p3.setNum(30);
    
            Consumer c1 = new Consumer(storage);
            Consumer c2 = new Consumer(storage);
            c1.setNum(15);
            c2.setNum(20);
    
            p1.run();
            p2.run();
            c1.run();
            c2.run();
            p3.run();
        }
    }
    

     运行结果如下:

    已生产产品数:10, 现产品量为:1
    已生产产品数:10, 现产品量为:2
    已生产产品数:10, 现产品量为:3
    已生产产品数:10, 现产品量为:4
    已生产产品数:10, 现产品量为:5
    已生产产品数:10, 现产品量为:6
    已生产产品数:10, 现产品量为:7
    已生产产品数:10, 现产品量为:8
    已生产产品数:10, 现产品量为:9
    已生产产品数:10, 现产品量为:10
    已生产产品数:20, 现产品量为:11
    已生产产品数:20, 现产品量为:12
    已生产产品数:20, 现产品量为:13
    已生产产品数:20, 现产品量为:14
    已生产产品数:20, 现产品量为:15
    已生产产品数:20, 现产品量为:16
    已生产产品数:20, 现产品量为:17
    已生产产品数:20, 现产品量为:18
    已生产产品数:20, 现产品量为:19
    已生产产品数:20, 现产品量为:20
    已生产产品数:20, 现产品量为:21
    已生产产品数:20, 现产品量为:22
    已生产产品数:20, 现产品量为:23
    已生产产品数:20, 现产品量为:24
    已生产产品数:20, 现产品量为:25
    已生产产品数:20, 现产品量为:26
    已生产产品数:20, 现产品量为:27
    已生产产品数:20, 现产品量为:28
    已生产产品数:20, 现产品量为:29
    已生产产品数:20, 现产品量为:30
    已消费产品数15, 现存量为:29
    已消费产品数15, 现存量为:28
    已消费产品数15, 现存量为:27
    已消费产品数15, 现存量为:26
    已消费产品数15, 现存量为:25
    已消费产品数15, 现存量为:24
    已消费产品数15, 现存量为:23
    已消费产品数15, 现存量为:22
    已消费产品数15, 现存量为:21
    已消费产品数15, 现存量为:20
    已消费产品数15, 现存量为:19
    已消费产品数15, 现存量为:18
    已消费产品数15, 现存量为:17
    已消费产品数15, 现存量为:16
    已消费产品数15, 现存量为:15
    要消费的产品量:20, 现库存量为:15,存量不足,暂时不能消费!
    

       这里有个问题:为了唤醒正在等待的线程,应该使用notify还是notifyAll?

      一般情况下,应该使用notifyAll,这是合理而保守的建议,它总会产生正确的结果,因为它可以保证将会唤醒所有需要被唤醒的线程。可能会唤醒一些其他的线程,但这不会影响程序的正确性,这些线程醒来之后,会检查他们正在等待的条件,如果发现条件并不满足,就会继续等待。
      
    从优化的角度来讲,如果处于等待状态的所有线程都在等待同一个条件,而每次只有一个线程可以从这个条件被唤醒,那么就应该选择notify,而不是notifyAll。
      

    2、BlockingQueue方法:

      直接使用wait和notify就像用“并发编程语言”进行编程一样,而java.util.concurrent则提供了更高级的语言,没有理由在新代码中使用wait和notify.即使有,也是极少的。下面我们对比一下阻塞队列方法BlockingQueue,它是java.util.concurrent下的主要用来控制线程同步的工具。

    public class BlockingQueue
    {
        private final int MAX_SIZE = 100;
        private LinkedBlockingQueue<Object> productList = new LinkedBlockingQueue<Object>(100);
    
        public void Produce(int num)
        {
            if (productList.size() == MAX_SIZE)
            {
                System.out.println("生产库存量为:" + MAX_SIZE + ",库存已满,暂时无法生产!");
            }
            for (int i = 1; i <= num; ++i)
            {
                try
                {
                    productList.put(new Object());
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                System.out.println("生产库存量为:" + productList.size());
            }
        }
    
        public void Consume(int num)
        {
            if (productList.size() == 0)
            {
                System.out.println("消费库存量为0,暂时不能消费!");
            }
            for (int i = 1; i <= num; ++i)
            {
                if (productList.size() < num)
                {
                    System.out.println(
                            "要消费的产品量:" + num + ", 现库存量为:" + productList.size() + ",存量不足,不能消费!");
                }
                try
                {
                    productList.take();
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            System.out.println("消费库存量:" + productList.size());
        }
    }
    
    public class Producer implements Runnable {
        private int num;
        private BlockingQueue storage;
    
        public Producer(BlockingQueue storage)
        {
            this.storage = storage;
        }
    
        public void run()
        {
            produce(num);
        }
    
        public void produce(int num)
        {
            storage.Produce(num);
        }
    
        public int getNum() {
            return num;
        }
    
        public void setNum(int num) {
            this.num = num;
        }
    
        public BlockingQueue getStorage() {
            return storage;
        }
    
        public void setStorage(BlockingQueue storage) {
            this.storage = storage;
        }
    }
    
    public class Consumer implements Runnable{
        private int num;
        private BlockingQueue storage;
    
        public Consumer(BlockingQueue storage)
        {
            this.storage = storage;
        }
    
        public void run()
        {
            consume(num);
        }
    
        public void consume(int num)
        {
            storage.Consume(num);
        }
    
        public int getNum() {
            return num;
        }
    
        public void setNum(int num) {
            this.num = num;
        }
    
        public BlockingQueue getStorage() {
            return storage;
        }
    
        public void setStorage(BlockingQueue storage) {
            this.storage = storage;
        }
    }
    
    public class BlockingQueueTest {
        public static void main(String[] args) {
            BlockingQueue storage = new BlockingQueue();
    
            Producer p1 = new Producer(storage);
            Producer p2 = new Producer(storage);
            Producer p3 = new Producer(storage);
            p1.setNum(10);
            p2.setNum(20);
            p3.setNum(30);
    
            Consumer c1 = new Consumer(storage);
            Consumer c2 = new Consumer(storage);
            c1.setNum(15);
            c2.setNum(20);
    
            p1.run();
            p2.run();
            c1.run();
            c2.run();
            p3.run();
        }
    }
    

      运行结果如下:

    生产库存量为:1
    生产库存量为:2
    生产库存量为:3
    生产库存量为:4
    生产库存量为:5
    生产库存量为:6
    生产库存量为:7
    生产库存量为:8
    生产库存量为:9
    生产库存量为:10
    生产库存量为:11
    生产库存量为:12
    生产库存量为:13
    生产库存量为:14
    生产库存量为:15
    生产库存量为:16
    生产库存量为:17
    生产库存量为:18
    生产库存量为:19
    生产库存量为:20
    生产库存量为:21
    生产库存量为:22
    生产库存量为:23
    生产库存量为:24
    生产库存量为:25
    生产库存量为:26
    生产库存量为:27
    生产库存量为:28
    生产库存量为:29
    生产库存量为:30
    消费库存量:15
    要消费的产品量:20, 现库存量为:15,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:14,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:13,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:12,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:11,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:10,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:9,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:8,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:7,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:6,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:5,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:4,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:3,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:2,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:1,存量不足,不能消费!
    要消费的产品量:20, 现库存量为:0,存量不足,不能消费!
    

      

     

      

  • 相关阅读:
    [AGC005D] ~K Perm Counting
    [国家集训队]middle
    CF842D Vitya and Strange Lesson
    浅谈脚本化css(三)之方块运动函数
    浅谈脚本化css(二)
    浅谈脚本化css(一)
    滚动条详解及制作(三)
    滚动条详解及制作(二)
    滚动条详解及制作(一)
    javascript定时器详解
  • 原文地址:https://www.cnblogs.com/hunterCecil/p/5631000.html
Copyright © 2011-2022 走看看