生产者消费者_【线程通信】生产者消费者模型

1 生产者消费者模型介绍

    生产者消费者模型,是每一个学习多线程的的人都需要知道的模型;

大致情况就是:有两个线程,一个负责生产产品,一个消费产品,两者公用同一块内存区域,也就是产品放在了同一块内存上面,如果两个线程没有采用一定的措施或者采用的策略错误的情况下,容易出现一系列的问题,例如数据一致性问题,死锁问题;

2be1db0a540c03191221ad0f2a9220ea.png

2 为什么需要生产者消费者模型     在多线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程;如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据;同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者;为了解决这个问题于是引入了生产者和消费者模式。      3 生产者-消费者模型(线程阻塞,线程唤醒)

    举例:线程1去奶茶,没有奶茶了,它就不执行了;线程二生产奶茶,通知线程1继续执行;

下面这个例子不大好,使用了Java线程已经抛弃的方法e65891ff86d2b141a2a8c4bdbec5b022.png

打印结果如下,最开始没奶茶,后来有了奶茶通知了挂起的线程,那个线程就得以继续执行

9fbace63eacb23e19a752c4d10acbe9e.png

上面这个就是经典的生产者-消费者模型,但是为啥这个例子当中的线程方法被弃用了呢?往下看一个例子

suspend和resume加锁导致死锁

07de13e883dc9c72ab5bdd74c20c1f4a.png

打印结果

e5051a5f12ddda9ac68b7f77a2680868.png

这个线程不用等了,一直都是在这里挂起了,竞争不到锁,没办法通知挂起的线程继续执行;

如果suspend比resume慢执行,也会导致线程永久挂起

e7a2c065aebff871e7cce1ae42aa7e82.png

打印结果,通知完了,那边才开始挂起

fbbe96ee079ef64979387aec309cf9f2.png

那么Java现在推荐哪一种方式进行使用呢~

wait/notify机制

这个机制要求这两个方法只能由同一对象锁的持有者线程进行调用,也就是卸载同步代码块里面,否则会抛出

IllegalMonitorStateException异常;

wait方法导致当前的线程进入等待状态,加入该对象的等待集合中,并发放弃当前持有的对象锁;

notify/notifyAll方法唤醒一个或所有正在等待这个对象锁的线程;

注意:虽然会wait自动解锁,但是对顺序有要求,如果在notify被调用之后才开始wait方法的调用,线程会永远处于WAITING状态

先来一个正常的演示(打印跟前面正常的一致)

37027edea70e9fd98ba29e0de19de96b.png

可以看到,如果是suspend/resume的话,这个程序是会导致死锁的,可是这里采用的是wait/notify机制,会自动释放锁

如果notify比waiting先执行,

那么会导致线程一直处于WAITING的状态

737581b1f782bdefdaa7c2c1cb5cb734.png

说个题外话,我觉得这个就跟你的女神已经通知你,我们不可能在一起了,然后你还一直在等待

还有另外一个机制

park/unpark机制

park表示等待一个“许可”

unpark表示授予一个"许可"

park/unpark机制有一个好处就是如果提前颁发“许可”了

也不会导致线程一直处于挂起或者是死锁的转态

但是它不会主动去释放锁

park比unpark提前执行的例子

e5051a5f12ddda9ac68b7f77a2680868.png本样式由 e5051a5f12ddda9ac68b7f77a2680868.png135编辑器出品,不允许任何第三方编辑器抄袭使用,违者

284ee741b8b18d6a7d26ab3179ab6b27.png

加锁导致死锁的例子

b7bc35e89d3afb64db89558cb6f6ccfe.png

【总结】

suspend/resume机制

resume先执行,suspend慢执行;resume/suspend加锁;都会导致死锁

wait/notify机制

wait/notify加锁了会自动释放锁,但是notify比wait先执行依然会线程永久挂起

park/unpark机制

park/unpark不会自动释放锁,但是先后执行顺序不会导致线程永久挂起

【提醒】

代码当中使用if语句来判断是否进入等待状态,

是错误的

官方建议是采用while情况下,判断是否可以将线程挂起

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值