多线程并发协作模型——生产者,消费者模型

生产者,消费者模型成员

生产者:生产产品,放入队列中
消费者:消费产品
队列:数据缓存区。

在这里插入图片描述

优点

1,解藕

生产者只关注生产,消费者只关注消费

2,异步

同步:a给b打电话,a要等b接通之后,a才能和b通话
异步:a给b发微信,a不必等回复,b也不必回复,b可以等有空了再回复

3,平衡速度差异

生成者的生产速度必须和消费者的消费速度持平,
不然,
生产>消费,就会导致队列溢出,
生产<消费,就会导致队列为空,

通知机制

在这里插入图片描述

wait():让当前线程等待
notify():唤醒一个线程
notifyAll():唤醒所有线程

逻辑:Q3中的线程被唤醒,进入Q1,抢锁,抢到锁的线程将在Q2中执行操作,执行操作之前检查队列满没满,满了,等待,没满执行操作,完了之后,释放锁。

因为Q2只能有一个线程,所以Q1中使用对象监视器锁机制

代码:

public class Producer implements Runnable{
    
    
    private Queue<Product> queue;
    private int maxCapacity;
 
    public Producer(Queue queue, int maxCapacity) {
    
    
        this.queue = queue;
        this.maxCapacity = maxCapacity;
    }
 
    @Override
    public void run() {
    
    
        synchronized (queue) {
    
    
            while (queue.size() == maxCapacity) {
    
     //一定要用 while,而不是 if,下文解释
                try {
    
    
                    System.out.println("生产者" + Thread.currentThread().getName() + "等待中... Queue 已达到最大容量,无法生产");
                    wait();
                    System.out.println("生产者" + Thread.currentThread().getName() + "退出等待");
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
            if (queue.size() == 0) {
    
     //队列里的产品从无到有,需要通知在等待的消费者
                queue.notifyAll();
            }
            Random random = new Random();
            Integer i = random.nextInt();
            queue.offer(new Product("产品"  + i.toString()));
            System.out.println("生产者" + Thread.currentThread().getName() + "生产了产品:" + i.toString());
        }
    }
}

逻辑:

1,生产者拿到锁,开始工作,检查生产箱满没满,满了,等待

2,生产者拿到锁,开始工作,检查生产箱满没满,没满,生产箱有没有产品,没有,通知消费者,然后

开始生产产品

public class Consumer implements Runnable{
    
    
    private Queue<Product> queue;
    private int maxCapacity;
 
    public Consumer(Queue queue, int maxCapacity) {
    
    
        this.queue = queue;
        this.maxCapacity = maxCapacity;
    }
 
    @Override
    public void run() {
    
    
        synchronized (queue) {
    
    
            while (queue.isEmpty()) {
    
    
                try {
    
    
                    System.out.println("消费者" + Thread.currentThread().getName() + "等待中... Queue 已缺货,无法消费");
                    wait();
                    System.out.println("消费者" + Thread.currentThread().getName() + "退出等待");
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
            if (queue.size() == maxCapacity) {
    
    
                queue.notifyAll();
            }
 
            Product product = queue.poll();
            System.out.println("消费者" + Thread.currentThread().getName() + "消费了:" + product.getName());
        }
    }
}

逻辑:

1,消费者拿到锁,开始消费产品,检查生产箱是否为空,为空,等待

2,消费者拿到锁,开始消费产品,检查生产箱是否为空,不为空,生产箱有没有装满产品,装满了,通

知生产者生产产品,开始消费产品

猜你喜欢

转载自blog.csdn.net/qq_36636312/article/details/109215375
今日推荐