生产者-消费者问题,实际上主要包含了两类线程,一种是生产者线程用于生产数据,另一种是消费者线程用于消费数据,为了解耦生产者和消费者的关系,通常会采用共享的数据区域存储产品。这个共享数据区域应该具备这样的线程间并发协作功能:
- 如果共享数据区已满,阻塞生产者继续生产数据放置入内;
- 如果共享数据区为空,阻塞消费者继续消费数据
为了实现生产者-消费者问题,可以采用三种方式:
1. 使用Object的wait/notify的消息通知机制
2. 使用Lock的Condition的await/signal的消息通知机制
3. 使用BlockingQueue实现
1. 使用Object的wait/notify的消息通知机制
wait
该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止。在调用 wait()之前,线程必须要获得该对象的对象监视器锁,即只能在同步方法或同步块中调用 wait()方法。调用wait()方法之后,当前线程会释放锁。如果调用wait()方法时,线程并未获取到锁的话,则会抛出IllegalMonitorStateException异常,这是以个RuntimeException。如果再次获取到锁的话,当前线程才能从wait()方法处成功返回。notify
该方法也要在同步方法或同步块中调用,即在调用前,线程也必须要获得该对象的对象级别锁,如果调用notify()时没有持有适当的锁,也会抛出IllegalMonitorStateException。该方法任意从WAITTING状态的线程中挑选一个进行通知,使得调用wait()方法的线程从等待队列移入到同步队列中,等待有机会再一次获取到锁,从而使得调用wait()方法的线程能够从wait()方法处退出。notifyAll
该方法与notify()方法的工作方式相同,重要的一点差异是:notifyAll使所有原来在该对象上wait的线程统统退出WAITTING状态。