zoukankan      html  css  js  c++  java
  • wait、notify应用场景(生产者-消费者模式)

    Java实现生产者消费者的方式有:wait && notify、BlockingQueue、Lock && Condition等

    wait、notify注意事项:
    (1)可以使用wait()和notify()方法在Java中实现线程间通信。不只是一个或两个线程,而是多个线程可以使用这些方法相互通信。
    (2)在synchronized方法或synchronized块中调用wait(),notify()和notifyAll()方法,否则JVM将抛出IllegalMonitorStateException。
    (3)从while(条件)循环调用wait和notify方法,而不是从if()块调用,因为要重复检查条件,而不仅仅是一次。
    (4)多使用notifyAll方法而不是notify。


    下面是wait、notify等待通知实现的生产者-消费者模式:
    生产者:

    /**
     * 生产者
     *
     * @author monkjavaer
     * @date 2018/12/15 11:13
     */
    public class Producer implements Runnable {
        /**
         * 产品容器
         */
        private final List<Integer> container;
    
        public Producer(List<Integer> container) {
            this.container = container;
        }
    
        /**
         * 生产者生产方法
         *
         * @throws InterruptedException
         */
        private void produce() throws InterruptedException {
            //产品容器容量
            int capacity = 5;
            synchronized (container) {
                //当容器已满,暂停生产
                while (container.size() == capacity) {
                    System.out.println("...容器已经满了,暂停生产...");
                    container.wait();
                }
                Random random = new Random();
                int p = random.nextInt(50);
                //模拟1秒生产一个产品
                TimeUnit.MILLISECONDS.sleep(1000);
                System.out.println("生产产品:" + p);
                container.add(p);
                container.notifyAll();
            }
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    produce();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("produce error");
                }
            }
        }
    }
    

      消费者:

    /**
     * 消费者
     * @author monkjavaer
     * @date 2018/12/15 11:13
     */
    public class Consumer implements Runnable{
    
        /**
         * 产品容器
         */
        private final List<Integer> container;
    
        public Consumer(List<Integer> container) {
            this.container = container;
        }
    
        /**
         * 消费者消费产品
         */
        private void consume() throws InterruptedException {
            synchronized (container){
                while (container.isEmpty()){
                    System.out.println("...容器是空的,暂停消费...");
                    container.wait();
                }
                Integer p = container.remove(0);
                //模拟1秒消费一个产品
                TimeUnit.MILLISECONDS.sleep(1000);
                System.out.println("消费产品:" + p);
                container.notifyAll();
            }
        }
        @Override
        public void run() {
            while (true){
                try {
                    consume();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println("consume error");
                }
            }
        }
    }
    

      测试:

    public class ProducerConsumerTest {
        public static void main(String[] args) {
            List<Integer> container = new ArrayList<>();
            Thread producer = new Thread(new Producer(container));
            Thread consumer = new Thread(new Consumer(container));
            producer.start();
            consumer.start();
        }
    }
    

      输出:

    生产产品:14
    生产产品:17
    消费产品:14
    生产产品:0
    生产产品:39
    生产产品:4
    生产产品:3
    ...容器已经满了,暂停生产...
    消费产品:17
    消费产品:0
    消费产品:39
    消费产品:4
    消费产品:3
    ...容器是空的,暂停消费...
    生产产品:25
    生产产品:33
    生产产品:17
    消费产品:25
    消费产品:33
    消费产品:17
    ...容器是空的,暂停消费...
    

      

  • 相关阅读:
    DES CBC java加密 php解密
    CocosCreator入门(一) ------ 简介、安装、微信小游戏
    H5游戏开发----CocosCreator、CocosCreator3D、Cocos2dX差异与选择
    GIT:git -c diff.mnemonicprefix=false -c core.quotepath=false revert --no-edit
    xxx was built without full bitcode" 编译错误解决
    程序猿之GitHub
    【北医三院】生孩、出院等事宜
    Unity:Andriod部分手机频繁闪退,vivo y55a等,Skipped 62 frames! The application may be doing too much work on its main thread
    初识LUA
    Unity3D开发之Matrix4x4矩阵变换
  • 原文地址:https://www.cnblogs.com/monkjavaer/p/10123687.html
Copyright © 2011-2022 走看看