多线程系列

线程间的通信

2020-01-24  本文已影响0人  小蜗牛Aaron

线程间的通信方式:

数据交互:

文件共享
网络共享
共享变量

线程间协作:

jdk提供的线程协调API,例如:suspend/resume、wait/notify、park/unpark

文件共享

文件共享.png

变量共享

变量共享.png

线程协作 - 场景

线程协作.png

API 被弃用的suspend和resume

作用:调用suspend挂起目标线程,通过resume可以恢复线程执行。

image.png

被弃用的主要原因是,容易写出死锁的代码

wait/notify机制

wait方法导致当前线程等待,加入该对象的等待集合中,并且放弃当前持有的对象锁。
notify/notifyAll方法唤醒一个或所有正在等待这个对象锁的线程。
注意1:虽然会wait自动解锁,但是对顺序有要求, 如果在notify被调用之后,才开始wait方法的调用,线程会永远处于WAITING状态。
注意2:这些方法只能由同一对象锁的持有者线程调用,也就是写在同步块里面,否则会抛出IllegalMonitorStateException异常


image.png

park/unpark机制

image.png

线程调用park则等待“许可” ,unpark方法为指定线程提供“许可(permit)”。 、

调用unpark之后,再调用park,线程会直接运行
提前调用的unpark不叠加,连续多次调用unpark后,第一次调用park后会拿到“许可”直接运行,后续调用会进入等待

image.png

伪唤醒

警告!!! 之前代码中用 if 语句来判断,是否进入等待状态,这样的做法是错误的!
官方建议应该在循环中检查等待条件,原因是处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出。 伪唤醒是指线程并非因为notify、notifyall、unpark等api调用而意外唤醒,是更底层原因导致的

上一篇下一篇

猜你喜欢

热点阅读