浅谈wait和notify方法(生产者和消费者案例)
java.lang.Object类提供了wait()、notify()、notifyAll()方法,这些方法只有在synchronized或synchronized代码块中才能使用,是否就会报java.lang.IllegalMonitorStateException异常。
当另外线程执行了某对象的notify方法之后,会唤醒在此对象等待池中的某个线程,使之成为可运行线程。notifyAll是唤醒在此对象等待池中所有的等待线程。
下面我们来看看一个比较经典的问题:生产者/消费者问题
问题描述如下:
生产者将产品交给店员,而消费者从店员处取走产品,店员一次只能持有固定数量的产品,如果生产者生产了过多的产品,店员会叫生产者等一下,如果店中有空位放产品了再通知;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取产品。
这里可能出现问题有以下两个:
1. 生产者比消费者快时,消费者会漏掉一些数据没有取到
2. 消费者比生产者快时,消费着会取相同的数据
- /**
- * 理解wait和notify方法
- * 生产者(Producer)/消费者(Consumer)问题
- * @author admin
- *
- */
- public class ProductTest
- {
- /**
- * @param args
- */
- public static void main(String[] args)
- {
- Clerk clerk = new Clerk();
- Thread producerThread = new Thread(new Producer(clerk));
- Thread consumerThread = new Thread(new Consumer(clerk));
- producerThread.start();
- consumerThread.start();
- }
- }
- /**
- * 店员
- * @author admin
- *
- */
- class Clerk
- {
- //最大产品数
- private static final int MAX_PRODUCT = 20;
- //最小产品数
- private static final int MIN_PRODUCT = 0;
- //默认为0个产品
- private int product = 0;
- /**
- * 生产者生产出来的产品交给店员
- */
- public synchronized void addProduect()
- {
- if(this.product >= MAX_PRODUCT)
- {
- try
- {
- wait();
- System.out.println("产品已满,请稍候再生产");
- }
- catch(InterruptedException e)
- {
- e.printStackTrace();
- }
- return;
- }
- this.product++;
- System.out.println("生产者生产第" + this.product + "个产品.");
- notifyAll(); //通知等待区的消费者可以取出产品了
- }
- /**
- * 消费者从店员取产品
- */
- public synchronized void getProduct()
- {
- if(this.product <= MIN_PRODUCT)
- {
- try
- {
- wait();
- System.out.println("缺货,稍候再取");
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- return;
- }
- System.out.println("消费者取走了第" + this.product + "个产品.");
- this.product--;
- notifyAll(); //通知等待去的生产者可以生产产品了
- }
- }
- /**
- * 生产品线程
- * @author admin
- *
- */
- class Producer implements Runnable
- {
- private Clerk clerk ;
- public Producer(Clerk clerk)
- {
- this.clerk = clerk;
- }
- public void run()
- {
- System.out.println("生产者开始生产产品.");
- while(true)
- {
- try
- {
- Thread.sleep((int)(Math.random() * 10) * 100);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- clerk.addProduect(); //生产产品
- }
- }
- }
- /**
- * 消费线程
- * @author admin
- *
- */
- class Consumer implements Runnable
- {
- private Clerk clerk;
- public Consumer(Clerk clerk)
- {
- this.clerk = clerk;
- }
- public void run()
- {
- System.out.println("消费者开始取走产品.");
- while(true)
- {
- try
- {
- Thread.sleep((int)(Math.random() * 10) * 100);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- clerk.getProduct(); //取产品
- }
- }
- }
总结:
对wait,notify,notifyAll方法理解可以为归纳为图所示
ps:最后一个o.notify是o.notifyAll,上传的时候没有注意到,抱歉了!

浙公网安备 33010602011771号