• 用 wait-notify 写一段代码来解决生产者-消费者问题


    在同步块中调用 wait() 和 notify()方法,如果阻塞,通过循环来测试等待条件。请参考答案中的示例代码。

    【生产者】

    import java.util.Vector;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class Producer implements Runnable {
    
        private final Vector sharedQueue;
        private final int SIZE;
    
        public Producer(Vector sharedQueue, int size) {
            this.sharedQueue = sharedQueue;
            this.SIZE = size;
        }
    
        @Override
        public void run() {
            // 生产数据
            for (int i = 0; i < 7; i++) {
                System.out.println("Produced:" + i);
                try {
                    produce(i);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    
        private void produce(int i) throws InterruptedException {
    
            // wait if queue is full
            while (sharedQueue.size() == SIZE) {
                synchronized (sharedQueue) {
                    System.out.println("Queue is full " + Thread.currentThread().getName()
                            + " is waiting , size: " + sharedQueue.size());
                    sharedQueue.wait();
                }
            }
    
            // producing element and notify consumers
            synchronized (sharedQueue) {
                sharedQueue.add(i);
                sharedQueue.notifyAll();
            }
        }
    }

    【消费者】

    import java.util.Vector;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class Consumer implements Runnable {
    
        private final Vector sharedQueue;
        private final int SIZE;
    
        public Consumer(Vector sharedQueue, int size) {
            this.sharedQueue = sharedQueue;
            this.SIZE = size;
        }
    
        @Override
        public void run() {
            // 消费数据
            while (true) {
                try {
                    System.out.println("Consumer: " + consume());
                    Thread.sleep(50);
                } catch (InterruptedException ex) {
                    Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    
        private int consume() throws InterruptedException {
    
            // wait if queue is empty
            while (sharedQueue.isEmpty()) {
                synchronized (sharedQueue) {
                    System.out.println("Queue is empty " + Thread.currentThread().getName()
                            + " is waiting , size: " + sharedQueue.size());
                    sharedQueue.wait();
                }
            }
    
            //otherwise consume element and notify waiting producer
            synchronized (sharedQueue) {
                sharedQueue.notifyAll();
                return (Integer) sharedQueue.remove(0);
            }
        }
    }

    【测试函数】

    import java.util.Vector;
    
    public class ProducerConsumerSolution {
    
        public static void main(String[] args) {
            Vector sharedQueue = new Vector();
            int size = 4;
            Thread prodThread = new Thread(new Producer(sharedQueue, size), "Producer");
            Thread consThread = new Thread(new Consumer(sharedQueue, size), "Consumer");
            prodThread.start();
            consThread.start();
        }
    }

    运行结果:

    Produced:0
    Queue is empty Consumer is waiting , size: 0
    Produced:1
    Consumer: 0
    Produced:2
    Produced:3
    Produced:4
    Produced:5
    Queue is full Producer is waiting , size: 4
    Consumer: 1
    Produced:6
    Queue is full Producer is waiting , size: 4
    Consumer: 2
    Consumer: 3
    Consumer: 4
    Consumer: 5
    Consumer: 6
    Queue is empty Consumer is waiting , size: 0
  • 相关阅读:
    dynamic和匿名对象
    生成1亿个不重复的8位随机整数
    Storage,Memcache,KVDB都是存储服务,如何区分何时用何种服务
    深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法
    常用工具
    数字格式化,保留一位小数,无小数用0补充
    学习某些API的方法
    程序员的学习方法(程序员必看)【风中叶老师讲述】
    html的dtd声明
    数据库管理工具navicat基本使用方法——以MySql为例
  • 原文地址:https://www.cnblogs.com/xbq8080/p/10371214.html
Copyright © 2020-2023  润新知