- /**
- * 等待唤醒之生产者和消费者模型
- * 生成者: 创建和添加数据的线程
- * 消费者: 销毁和删除数据的线程
- * 问题 1: 生成者生成数据过快, 消费者消费数据相对慢, 不接收数据了, 会造成数据丢失
- * 问题 2: 消费者消费数据过快, 生成者生成数据相对慢, 不发送数据了, 会造成数据被重复读取
- * 总结 : 生产数据过快会造成数据丢失
- * 生成数据过慢会造成数据被重复读取
- *
- *
- * wait()和 notifyAll()用法:
- * 1. 必须是同一个对象的 wait()和和 notifyAll()方法
- * 2. wait()和 notifyAll()必须用在同步方法或同步代码块中
- * 3. wait()存在中断和虚假唤醒 (多个生成者和消费者线程等待时会出现虚假唤醒) 问题,
- * 虚假唤醒: 多个消费者线程等待时, 唤醒后, 都会接着执行同步方法中未完成的代码
- * 解决办法 : wait()必须放在 while 循环中 , 即在线程被唤醒后 先继续进行判断, 不符合条件就继续等待 `
- */
- public class ProductorAndConsumerTest {
- public static void main(String[] args) {
- Clerk clerk = new Clerk();
- Productor productor = new Productor(clerk);
- Consumer consumer = new Consumer(clerk);
- new Thread(productor, "生成者 A").start();
- new Thread(consumer, "消费者 B").start();
- new Thread(productor, "生成者 C").start();
- new Thread(consumer, "消费者 D").start();
- }
- }
- // 店员 持有产品
- class Clerk{
- private int product = 0;
- public synchronized void getPro() throws InterruptedException {
- // wait()必须处在 while 循环体中
- while (product>= 1){
- System.out.println("产品已满!");
- this.wait();
- }
- System.out.println(Thread.currentThread().getName() + "生产了产品" + (++product));
- this.notifyAll();
- }
- public synchronized void sale() throws InterruptedException {
- // wait()必须处在 while 循环体中
- while (product <= 0){
- System.out.println(Thread.currentThread().getName() + "缺货!");
- this.wait();
- }
- System.out.println(Thread.currentThread().getName() + "消费了产品" + (--product));
- this.notifyAll();
- }
- }
- // 生产者线程
- class Productor implements Runnable{
- private Clerk clerk;
- public Productor(Clerk clerk) {
- this.clerk = clerk;
- }
- @Override
- public void run() {
- for (int i = 0; i < 20; i++) {
- try {
- clerk.getPro();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- // 消费者线程
- class Consumer implements Runnable{
- private Clerk clerk;
- public Consumer(Clerk clerk) {
- this.clerk = clerk;
- }
- @Override
- public void run() {
- for (int i = 0; i < 20; i++) {
- try {
- clerk.sale();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
来源: http://www.bubuko.com/infodetail-2864053.html