使用wait和notifyAll实现生产者消费者模型

来源:互联网 发布:淘宝q币充值改金额 编辑:程序博客网 时间:2024/06/01 16:25

wait和notifyAll是JDK中Object类的两个方法,主要用来线程间通讯,最经典的应用场景就是【生产者-消费者】,下面给出简单示例。

/** * @Auothor wzx * @Date 2017/5/7 0007 */public class ProducerConsumer {    public static void main(String[] args) {        Queue<Integer> buffer = new LinkedList<>();        int maxSize = 10;        Thread producer = new Thread(new Producer(buffer, maxSize));        Thread consumer = new Thread(new Consumer(buffer));        producer.start();        consumer.start();    }    static class Producer implements Runnable {        private Queue<Integer> queue;        private int maxSize;        Producer(Queue<Integer> queue, int maxSize) {            this.queue = queue;            this.maxSize = maxSize;        }        @Override        public void run() {            while (true) {                synchronized (queue) {                    while (queue.size() == maxSize) {                        System.out.println("Queue is full,producer thread waiting for "                                + " consumer to take something from queue");                        try {                            queue.wait();                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    Random random = new Random();                    int i = random.nextInt();                    System.out.println("Producing value :" + i);                    queue.add(i);                    queue.notifyAll();                }            }        }    }    static class Consumer implements Runnable {        private Queue<Integer> queue;        Consumer(Queue<Integer> queue) {            this.queue = queue;        }        @Override        public void run() {            while (true) {                synchronized (queue) {                    while (queue.isEmpty()) {                        System.out.println("Queue is empty,Consumer thread is waiting"                            + " for producer thread to put something in queue");                        try {                            queue.wait();                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                    }                    System.out.println("Consuming value :" + queue.remove());                    queue.notifyAll();                }            }        }    }}

执行结果如下:

Producing value :-306191693Producing value :1230823506Producing value :-1295070113Producing value :-330157665Producing value :1580771896Producing value :571342129Producing value :1798066124Producing value :247966176Producing value :1149189440Producing value :-1506596231Queue is full,producer thread waiting for  consumer to take something from queueConsuming value :-306191693Consuming value :1230823506Consuming value :-1295070113Consuming value :-330157665Consuming value :1580771896Consuming value :571342129Consuming value :1798066124Consuming value :247966176Consuming value :1149189440Consuming value :-1506596231Queue is empty,Consumer thread is waiting for producer thread to put something in queue

使用wait和notifyAll方法需要注意:
1.一定要在synchronized 方法或synchronized 代码块中使用,否则JVM或抛出IllegalMonitorStateException异常;
2.使用wait方法使用while循环判断条件,避免被假唤醒;
3.synchronized 使用的一定是同个锁对象;

参考
http://javarevisited.blogspot.com/2015/07/how-to-use-wait-notify-and-notifyall-in.html#axzz4gOjkc8Yu
http://javarevisited.blogspot.com/2011/05/wait-notify-and-notifyall-in-java.html

0 0
原创粉丝点击