经典案例:生产者和消费者
一、什么是生产者和消费者?
生产者与消费者问题是多线程同步的一个经典问题。生产者和消费者同时使用一块缓冲区,生产者生产商品放入缓冲区,消费者从缓冲区中取出商品。我们需要保证的是,当缓冲区满时,生产者不可生产商品;当缓冲区为空时,消费者不可取出商品。
二、如何解决一个生产者与消费者问题
主要三种解决方式:
-
wait()与notify()方法
-
Lock与Condition机制
-
BlockingQueue阻塞队列
1.wait()与notify()方法
wait()方法使用条件:
wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
- 当生产产品数量满时,调用wait()方法,使得生产者释放锁,当前线程阻塞,消费者线程可以获得锁。
- 当产品数量为空时,调用wait()方法,使得消费者释放锁,当前线程阻塞,生产者线程可以获得锁。
notify()方法使用条件:
notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
- 如果刚执行的是消费者,那么产品数量为0,就执行wait()方法等待。那么在执行生产者时,只要生产一个产品就会通过notify()方法唤醒消费者,让消费者来消费产品。
- 如果生产者生产产品过快,消费者来不及消费,并且到达产品上限。那么生产者就执行wait()方法等待。在消费者消费一个产品就会通过notify()方法唤醒生产者,让生产者生产产品。
代码如下:
//调度类
public class Clerk {
//共享资源 产品数量
private static int productCount = 0;
//生产产品
//必须加上同步方法,不然两个线程会产生线程安全问题
public synchronized void produceProduct(){
if (productCount < 20){
productCount++;
System.out.println(Thread.currentThread().getName() + ":开始生产第" + productCount + "个产品");
//唤醒等待的消费者
notify();
}else {