生产者消费者问题(生产者和消费者都阻塞于同一把锁this锁)

简介: 生产者消费者问题(生产者和消费者都阻塞于同一把锁this锁)

公众号merlinsea


问题介绍:利用线程间通信机制wait,notify完成多生产者,多消费者问题。

生产者消费者问题特点:

1、生产者生产的时候消费者不能消费,消费者消费的时候生产者不能生产

2、生产者和消费者阻塞于同一把锁

640.jpg


核心点:

1、生产者和消费者是有多个的,因此每个生产者和消费者都是单独的一个线程

2、这些所有的生产者和消费者公用一个中间商

3、这些消费者共用一把锁,这些生产者公用一把锁


代码实现:

中间商Medium


public class Medium {
    //现有库存
    private int num = 0;
    //最大容量
    private static final int TOTAL = 20;
    /**
     * 接收生产数据
    */
    public synchronized void put() {
        //判断当前的库存,是否已经是最大的库存容量
        if (num < TOTAL) {
            //如果不是,生产完成之后,通知消费者进行消费
            System.out.println("新增库存-------->当前库存" + ++num);
            try {
                Thread.sleep(500L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            notifyAll();
        } else {
            //如果是,则通知生产者进行等待
            try {
                System.out.println("新增库存---------> 库存已满"+num);
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 获取消费数据
     */
    public synchronized void take() {
        //判断当前库存是否不足
        if (num > 0) {
            //如果充足,在消费完成之后通知生产者进行生产
            System.out.println("消费库存-----------> 当前库存容量" + --num);
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            notifyAll();
        } else {
            //如果不足,通知消费者暂停消费
            System.out.println("消费库存-----------> 库存不足"+num);
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


消费者Consumer

public class Consumer implements Runnable{
    private Medium medium;
    /**
     * 通过外界传入中间商,可以保证所有消费者共用一把锁
     * @param medium
     */
    public Consumer(Medium medium) {
        this.medium = medium;
    }
    @Override
    public void run() {
        while (true) {
            medium.take();
        }
    }
}


生产者Producer

public class Producer implements Runnable {
    private Medium medium;
    /**
     * 通过外界传入中间商,可以保证所有生产者共用一把锁
     * @param medium
     */
    public Producer(Medium medium) {
        this.medium = medium;
    }
    @Override
    public void run() {
        while (true) {
            medium.put();
        }
    }
}


启动类Main

   需要注意的是我们的启动类中是将同一个中间商同时传递给了生产者和消费者,因此生产者和消费者中执行take()和put()操作的时候是公用同一把this锁(即同一个中间商锁)。

public class Main {
    public static void main(String[] args) {
        // 构造中间商
        Medium medium = new Medium();
        // 构造消费者
        new Thread(new Consumer(medium)).start();
        // 构造生产者
        new Thread(new Producer(medium)).start();
    }
}


代码文件组织结构

640.jpg


vip算法班永久学习班: 800元/人

周一、周三、周五:8:30-9:30,周六、周日:10:30-11:30

报名方式:通过公众号导航栏的刷题群即可联系到我的微信号

vip算法班详情链接如下:

奔跑的小梁,公众号:梁霖编程工具库算法训练营快来参加吧~
相关文章
|
5月前
|
容器
多线程学习之生产者和消费者与阻塞队列的关系
多线程学习之生产者和消费者与阻塞队列的关系
22 0
|
7月前
|
安全 API C++
c++生产者和消费者线程循环
线程安全-生产者消费者模型
75 1
|
6月前
|
Java
线程等待唤醒(等待通知)机制
线程等待唤醒(等待通知)机制
20 0
|
9月前
|
算法
生产者消费者问题(生产者和消费者分别阻塞于不同的锁)
生产者消费者问题(生产者和消费者分别阻塞于不同的锁)
|
11月前
|
数据可视化
高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析
高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析
37 0
|
安全 数据处理
线程中的生产者和消费者模式
线程中的生产者和消费者模式
100 0
线程中的生产者和消费者模式
|
调度
【多线程:锁】生产者消费者
【多线程:锁】生产者消费者
148 0
基于阻塞队列实现的简单生产者-消费者模式
基于阻塞队列实现的简单生产者-消费者模式
89 0