生产者消费者问题(生产者和消费者分别阻塞于不同的锁)

简介: 生产者消费者问题(生产者和消费者分别阻塞于不同的锁)

公众号merlinsea


背景介绍:


   之前介绍了生产者消费者阻塞在同一把this锁的解决方案,但那个方案会导致生产者和消费者互斥,即生产者生产的时候消费者不能进行消费或者消费者消费的时候生产者不能进行生产,为了解决这个问题,故提出了如下解决方案。


生产者消费者问题介绍

奔跑的小梁,公众号:梁霖编程工具库生产者消费者问题(生产者和消费者都阻塞于同一把锁this锁)


利用condition优化之前的生产者和消费者问题

特点:

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

2、生产者和消费者分别阻塞于不同的锁

640.jpg


中间商Medium

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


消费者consumer

/**
 * 消费者
 */
public class Consumer implements Runnable{
    private Medium 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;
    public Producer(Medium medium) {
        this.medium = medium;
    }
    @Override
    public void run() {
        while (true) {
            medium.put();
        }
    }
}


main函数

public class Main {
    public static void main(String[] args) {
        Medium medium = new Medium();
        new Thread(new Consumer(medium)).start();
        new Thread(new Consumer(medium)).start();
        new Thread(new Producer(medium)).start();
        new Thread(new Producer(medium)).start();
        new Thread(new Producer(medium)).start();
        new Thread(new Producer(medium)).start();
    }
}


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

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

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

vip算法班详情链接

奔跑的小梁,公众号:梁霖编程工具库算法训练营快来参加吧~
相关文章
|
容器
多线程学习之生产者和消费者与阻塞队列的关系
多线程学习之生产者和消费者与阻塞队列的关系
50 0
|
4月前
|
算法 Java
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题
该博客文章综合介绍了Java并发编程的基础知识,包括线程与进程的区别、并发与并行的概念、线程的生命周期状态、`sleep`与`wait`方法的差异、`Lock`接口及其实现类与`synchronized`关键字的对比,以及生产者和消费者问题的解决方案和使用`Condition`对象替代`synchronized`关键字的方法。
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题
|
6月前
|
并行计算 安全 Go
可重入锁实现消费者和生产者的例子
【6月更文挑战第28天】本文探讨了Python和Go中使用可重入锁(RLock)进行线程同步以及异步操作。异步存取示例展示了goroutine的并发优势,启动简单且运行异步。goroutine的调度和并发处理能力是其高效并发的关键。
35 0
可重入锁实现消费者和生产者的例子
|
6月前
|
安全 Java 容器
线程池,定时器以及阻塞队列(生产者/消费者模型)
线程池,定时器以及阻塞队列(生产者/消费者模型)
47 0
|
安全 API C++
c++生产者和消费者线程循环
线程安全-生产者消费者模型
100 1
生产者消费者问题(生产者和消费者都阻塞于同一把锁this锁)
生产者消费者问题(生产者和消费者都阻塞于同一把锁this锁)
|
数据可视化
高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析
高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析
55 0
|
安全 数据处理
线程中的生产者和消费者模式
线程中的生产者和消费者模式
129 0
线程中的生产者和消费者模式
|
安全 Java
Java多线程——生产者/消费者问题
生产者/消费者问题
164 0
基于阻塞队列实现的简单生产者-消费者模式
基于阻塞队列实现的简单生产者-消费者模式
115 0