
java并发学习18:保护性暂停模式
发布日期:2021-05-07 02:04:29
浏览次数:15
分类:精选文章
本文共 2863 字,大约阅读时间需要 9 分钟。
1、定义
保护性暂停,即Guarded Suspension,用在一个线程等待另一个线程的执行结果
- 有一个结果需要从一个线程传递到另一个线程,让他们关联同一个GuardedObject
- 如果有结果不断从一个线程到另一个线程那么可以使用消息队列(生产者/消费者)
- jdk中,Join的实现,Future的实现,采用的就是此模式
- 因为要等待另一方的结果,因此归类到同步模式
2、实现
class GuardedObject { //结果 private Object response; //获取结果 public Object get() { synchronized (this) { //没有结果 while(response == null) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } return response; } } //产生结果 public void complete(Object response) { synchronized (this) { //给结果成员变量赋值 this.response = response; this.notifyAll(); } }}
3、增加超时
class GuardedObject { //结果 private Object response; //获取结果 public Object get(long timeout) { synchronized (this) { //开始时间 long begin = System.currentTimeMillis(); //经历时间 long passedTime = 0; while(response == null) { //经历的时间超过了最大等待时间时,退出循环 if(passedTime >= timeout) { break; } try { this.wait(timeout); } catch (InterruptedException e) { e.printStackTrace(); } //求得经历时间 passedTime = System.currntTimeMillis() - begin; } return response; } } //产生结果 public void complete(Object response) { synchronized (this) { //给结果成员变量赋值 this.response = response; this.notifyAll(); } }}
4、join原理
底层也是wait,notify实现
5、解耦等待和生产
图中Futures 就好比居民楼一层的信箱(每个信箱有房间编号),左侧的t0,t2,t4就好比等待邮件的居民,右侧的t1, t3,t5就好比邮递员
如果需要在多个类之间使用GuardedObject对象,作为参数传递不是很方便,因此设计一个用来解耦的中间类,这样不仅能够解耦【结果等待者】和【结果生产者】,还能够同时支持多个任务的管理class People extends Thread { public void run() { //收信 GuardedObject guardedObject = Mailboxes.createGuardedObject(); Object mail = guardedObject.get(5000); }}class Postman extends Thread { private int id; private String mail; //送信 public void run() { GuardedObject guardedObject = Mailboxes.getGuardedObject(id); guardedObject.complete(mail) }}class Mailboxes { private Mapboxes = new Hashtable<>(); private static int id = 1; //产生唯一id private static synchronized int generateId() { return id++; } public static GuardedObject getGuardObject(int id) { return boxes.get(id); } public static GuardedObject createGuaredeObject(){ GuardedObject go = new GuardedObject(generateId()); boxes.put(go.getId(),go); reeturn go; } public static Set getIds() { return boxes.keySet(); }}
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月14日 17时38分22秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
趣谈win10常用快捷键
2019-03-04
11.2.6 时间值的小数秒
2019-03-05
Redis源码分析(七)--- zipmap压缩图
2019-03-05
【MySQL】(九)触发器
2019-03-05
Oracle 11G环境配置
2019-03-05
【Python】(十二)IO 文件处理
2019-03-05
【Oozie】(三)Oozie 使用实战教学,带你快速上手!
2019-03-05
师兄面试遇到这条 SQL 数据分析题,差点含泪而归!
2019-03-05
C语言的数值溢出问题(上)
2019-03-05
8051单片机(STC89C52)以定时器中断模式实现两倒计时器异步计时
2019-03-05
vue项目通过vue.config.js配置文件进行proxy反向代理跨域
2019-03-05
android:使用audiotrack 类播放wav文件
2019-03-05
聊聊我的五一小假期
2019-03-05
数据库三个级别封锁协议
2019-03-05
ACM/NCPC2016 C Card Hand Sorting(upc 3028)
2019-03-05
ubuntu学习笔记-常用文件、命令以及作用(hosts、vim、ssh)
2019-03-05
SLAM学习笔记-求解视觉SLAM问题
2019-03-05
普歌-允异团队-HashMap面试题
2019-03-05