并发编程(四):线程基本API和线程状态

2021-03-10  本文已影响0人  圆企鹅i

1. wait&notify

1.1 简单谈谈

相信大家,都应该在对象里面找过他的api
有没有发现,对象里面都有wait notify notifyAll这些个方法了

因为他们都是来自终极父类Object 为啥Object要有这api啊
因为之前提到了 java设计对象的时候 在对象的身体里 封印了锁
当你还没有遇到那个给你锁的人之前 这些能力(API)是没有用的

直到那一天 遇到了那个让你获得锁的人
所以啊 这些都建立在获得重量级锁 向操作系统申请了Monitor这把大锁的前提下

1.2 为啥要设计这几个API

还是来一个场景
让我们梦回那个夏天,小学奥数之时间最少问题
洗好水壶,灌上凉水,放在火上;在等待水开的时间里,洗茶壶、洗茶杯、拿茶叶;等水开
了,泡茶喝。
但是心狠手辣的资本家 ,开了想要讲究效率,开10个线程(打工人)来干活
洗茶壶(1)
灌上凉水(1)
放在火上(1)
洗茶杯(1)
拿茶叶(1)
泡茶喝(1)
每一个人都是做那个事情的翘楚 洗茶壶的洗茶壶贼6 拿茶叶的拿茶叶贼6
但是操作间只有一个,
就出现了一个问题,泡茶佬 身强力壮冲到操作间,草!(一种植物) 没茶喝!凸(艹皿艹 )
然后他就出现了,床! 这个时代最伟大的发明,进来没事做的 可以在床上休息一下(此处就不说睡了)怕误解

因为工作间的规定要适用于大部分人,然后老板开始定规矩了
1. 操作间,进来纯靠抢,默认最猛的男人干活最快
2. 进来但是条件不足,不能干活的,床上休息
3. 干完活的人,告诉那个需要你的老哥,该干活了
4. 休息了很久的老哥,不一定是最猛的男人,所以得去门口强,强烈遵循条例1

然后现象就是这样了
泡茶佬先进来>>>凸(艹皿艹 )没茶喝>>>床上休息
茶杯佬冲进来>>>洗了个茶杯>>>登记一下 我洗完茶杯了!溜了
放火佬进来>>>凸(艹皿艹 )茶壶没洗>>>床上休息
茶壶佬进来>>>洗个茶壶>>>登记一下 我洗完茶壶了!溜了
灌水佬进来>>>进来茶壶灌水>>>登记一下!诶 可以烧水了 叫灌水佬去门口排队
茶叶佬进来>>>放个茶叶>>>登记一下!溜了
放火佬进来>>>放火烧个水>>>登记一下!叫泡茶佬可以泡茶了
泡茶佬进来>>>泡茶>>>ok

有智慧的老哥会发现,你这根本没有提高效率啊!比我一个人做(单线程)还慢!
老板就是爱使唤人! 就是让我们每个人打工,不想我们闲下来!

其实只是我阴暗的心理,在丑化资本主义而已

真正的业务场景肯定是,很多人同时开始干活,同时洗茶杯,洗茶壶,放茶叶,等到这些事情做完了
该烧水了或者该泡茶了 就叫醒对应的大哥

肯定干活效率比单线程快很多啦!

后面会聊聊 java.util.concurrent的CountDownLatch
通常我们在业务中,要多线程执行一些活 ,把任务分成十几个让线程去干
然后我们卡住主线程,活干完之后,计数器统计活干完了,让主线程把结果推给用户。
ps:(这里是用户需要结果,不需要结果直接异步

1.3 原理
image.png

obj.wait() 让进入 object 监视器的线程到 waitSet 等待
obj.notify() 在 object 上正在 waitSet(床)等待的线程中挑一个唤醒
obj.notifyAll() 让 object 上正在 waitSet(床) 等待的线程全部唤醒

它们都是线程之间进行协作的手段,都属于 Object 对象的方法。必须获得此对象的锁,才能调用这几个方法

wait() 方法会释放对象的锁,进入 WaitSet 等待区,从而让其他线程就机会获取对象的锁。无限制等待,直到notify 为止
wait(long n) 有时限的等待, 到 n 毫秒后结束等待,或是被 notify

(未完)

感谢:

《Java并发编程的艺术》方腾飞,魏鹏,程晓明
《Java并发实现原理:JDK源码剖析》余春龙
全面深入学习java并发编程,java基础进阶中级必会教程_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

上一篇 下一篇

猜你喜欢

热点阅读