目录

  • 3.15 同步模式之保护性暂停
    • 1、基本使用
    • 2、拓展: 增加超时
    • 3、拓展: 增加测试
    • 4、原理之join
    • 5、扩展: 解耦

3.15 同步模式之保护性暂停

1、基本使用

用一个线程等待另一个线程的执行结果

要点:

  • 有一个结果需要从一个线程传递另一个线程,让他们关联同一个Object
  • 如果有结果不断从一个线程传递到另一个线程那么可以使用消息队列(见消费者、生产者)
  • JDK中,join的实现,Future的实现,采用的就是此模式
  • 因为要等待另一方的结果,因此归类到同步模式

package com.sharing_model.protective_pause;import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;/*** 读取数据*/
public class Downloader {public static List<String> downLoad() throws Exception {HttpURLConnection conn = (HttpURLConnection) new URL("https://www.baidu.com/").openConnection();List<String> lines = new ArrayList<>();try(BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {String line;while ((line = reader.readLine()) != null) {lines.add(line);}}return lines;}
}
package com.sharing_model.protective_pause;import java.util.List;/*** 同步模式之保护性暂停*/
public class ProtectivePause {public static void main(String[] args) {//线程1 等待 线程2GuardedObject guardedObject = new GuardedObject();//等待结果new Thread(() -> {Object o = guardedObject.get();System.out.println(o);}).start();//下载结果new Thread(() -> {try {List<String> list = Downloader.downLoad();guardedObject.complete(list);} catch (Exception e) {e.printStackTrace();}}).start();}
}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();}}}

2、拓展: 增加超时

package com.sharing_model.protective_pause;import java.util.List;/*** 同步模式之保护性暂停* 扩展: 超时*/
public class ProtectivePauseAddMoreTime {public static void main(String[] args) {//线程1 等待 线程2GuardedObject1 guardedObject = new GuardedObject1();//等待结果new Thread(() -> {Object o = guardedObject.get(2*1000);System.out.println(o);}).start();//下载结果new Thread(() -> {try {List<String> list = Downloader.downLoad();guardedObject.complete(list);} catch (Exception e) {e.printStackTrace();}}).start();}
}class GuardedObject1 {//结果private Object response;//获取结果public Object get(long timeout) {synchronized (this) {//开始时间long begin = System.currentTimeMillis();//经历的时间long passedTime = 0;//没有结果while (response == null) {long waitTime = timeout - passedTime;if (waitTime <= 0) {break;}try {this.wait(waitTime);} catch (InterruptedException e) {e.printStackTrace();}//求得经历的时间passedTime = System.currentTimeMillis() - begin;}return response;}}//产生结果public void complete(Object response) {synchronized (this) {//给结果成员变量赋值this.response = response;this.notifyAll();}}}

3、拓展: 增加测试

演示:https://www.bilibili.com/video/BV16J411h7Rd?p=101

4、原理之join

演示:https://www.bilibili.com/video/BV16J411h7Rd?p=101

5、扩展: 解耦

图中Futures就好比居民楼一层的信箱(每个信箱有房间编号)左侧的t0,t2,t4就好比等待邮件的居民,右侧的t1,t3,t5就好比邮递员

如果需要在多个类之间使用GuardedObject对象,作为参数传递不是很方便,因此设计一个用来解耦的中间类,这样不仅能够解构【结果等待者】和【结果生产者】,还能同时支持多个任务的管理

package com.sharing_model.protective_pause;import java.util.Hashtable;
import java.util.Map;
import java.util.Set;/*** 同步模式之保护性暂停* 扩展: 解耦*/
public class ProtectivePauseAddDecoupling {public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 3; i++) {new People().start();}Thread.sleep(1);for (Integer id : Mailboxes.getIds()) {new Postman(id, "居民id为: " + id +"的内容").start();}}
}//居民类
class People extends Thread {@Overridepublic void run() {//收信GuardedObject3 guardedObject = Mailboxes.createGuardedObject();System.out.println("开始收信id: " +  guardedObject.getId());Object o = guardedObject.get(5*1000);System.out.println("收到信id: " + guardedObject.getId() + " " + o );}
}//邮递员类
class Postman extends Thread {private int id;private String mail;public Postman(int id, String mail) {this.id = id;this.mail = mail;}@Overridepublic void run() {GuardedObject3 guardObject = Mailboxes.getGuardObject(id);guardObject.complete(mail);System.out.println("开始送信id: " + id + " " + mail);}@Overridepublic long getId() {return id;}public void setId(int id) {this.id = id;}public String getMail() {return mail;}public void setMail(String mail) {this.mail = mail;}}class Mailboxes {private static Map<Integer, GuardedObject3>  boxes = new Hashtable<>();private static int id = 1;//产生唯一idprivate static synchronized int generateId() {return id++;}public static GuardedObject3 createGuardedObject() {GuardedObject3 go = new GuardedObject3(generateId());boxes.put(go.getId(), go);return go;}public static Set<Integer> getIds() {return boxes.keySet();}public static GuardedObject3 getGuardObject(int id) {return boxes.remove(id);}}class GuardedObject3 {//标识Guarder Objectprivate int id;public GuardedObject3(int id) {this.id = id;}public int getId() {return id;}public void setId(int id) {this.id = id;}//结果private Object response;//获取结果public Object get(long timeout) {synchronized (this) {//开始时间long begin = System.currentTimeMillis();//经历的时间long passedTime = 0;//没有结果while (response == null) {long waitTime = timeout - passedTime;if (waitTime <= 0) {break;}try {this.wait(waitTime);} catch (InterruptedException e) {e.printStackTrace();}//求得经历的时间passedTime = System.currentTimeMillis() - begin;}return response;}}//产生结果public void complete(Object response) {synchronized (this) {//给结果成员变量赋值this.response = response;this.notifyAll();}}}

同步模式之保护性暂停相关推荐

  1. 【Java并发】同步模式之保护性暂停

    public class 设计模式_保护性暂停 {public static void main(String[] args) {GuardedObject guardedObject = new G ...

  2. 并发设计模式——保护性暂停(Guarded Suspension)

    并发设计模式--保护性暂停(Guarded Suspension) 什么叫做 Guarded Suspension ? guarded 的意思是"守护.担保",suspension ...

  3. 以太坊Geth几种同步模式

    链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载. 以太坊Geth几种同步模式 同步模式分类 –fast Enable fast syncing through s ...

  4. Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结

    同步和异步:与消息的通知机制有关. 本质区别 现实例子 同步模式 由处理消息者自己去等待消息是否被触发 我去银行办理业务,选择排队等,排到头了就办理. 异步模式 由触发机制来通知处理消息者 我去银行办 ...

  5. java线程-保护性暂停(wait,notify实现)

    考虑以下场景需求: A同学计算一个结果res B同学需要等待A同学的结果res 需要用到保护性暂停:一个线程等待另外一个线程的执行结果 这里我们让A,B同学关联到一个类. B同学一直等待A同学 imp ...

  6. 同步模式下的端口映射程序

    今天打算写一个FtpServer玩一下的,需要看看ftp软件常用命令形式(完整实现所有ftp命令太麻烦),最开始打算通过抓包看cuteftp是如何访问ftpserver的,但要把其中的命令保存下来还得 ...

  7. mysql 主主模式优缺点_mysql主主同步模式

    主192.168.56.20 和 从都新建数据库db1 db2 db3(如果数据库在用,需要上锁后手动从主备份,然后在从恢复) mysql> create database db1; Query ...

  8. mysql 半同步关闭_MySQL的半同步模式配置

    1.什么是半同步? 在有一台主服务器.多台从服务器的情况下,主服务器只会等待一台从服务器同步数据. 2.为什么要使用半同步? 在使用同步模式时,数据的写速度太慢. 在使用异步模式时,可能会造成从服务器 ...

  9. MySQL 迁移到半同步模式

    下面实验是基于http://5073392.blog.51cto.com/5063392/1536487搭建的 1) 在master上安装插件 mysql> install plugin rpl ...

  10. MFC win32 API串口同步模式代码示范

    win32 API串口同步模式代码示范 源文件下载: vs2015打开 文件名: MFC_Win32API_同步串口.rar 在OnInitDialog()位置初始化串口: handleFile1 = ...

最新文章

  1. mysql数据库比对视频教程_MySQL数据库全学习实战视频教程(27讲 )
  2. 安徽理工大学计算机技术研究生,安徽理工大学(专业学位)计算机技术研究生辅导...
  3. Thinkphp框架中D()和M()的区别
  4. PHP部分字符串函数汇总
  5. oa部署mysql_oa系统部署
  6. android 删除路径文件内容,Android 删除已知路径的文件或文件夹
  7. QT VS环境安装后出现生成的程序can not start, can not find Qt pligins “windos“ 问题 2021-06-13
  8. php写带分页的留言板,php中分页程序之基于留言板详解_PHP教程
  9. git merge 回退_Git 基础学习总结2(学不会你锤我)
  10. 「附身」马云、恶搞特朗普,AI新应用助你上演「大咖模仿秀」
  11. ios 内存管理的理解(五)ARC使用特点及注意事项
  12. Zookeeper的ZAB协议和Leader选举过程剖析
  13. linux环境下主从复制,Linux之CentOS上配置MariaDB主从复制
  14. 计算机一级插入页眉,2017年计算机一级WPS辅导:WPS中页眉页脚的设计技巧
  15. 受新冠病毒影响,谷歌延迟发布 Chrome 和 Chrome OS 安全更新版本
  16. java图片颜色取反色,照片底片模式
  17. centos7 网卡命名
  18. WPF - 属性系统 (4 of 4)
  19. 有限元法 有限差分法 有限体积法
  20. python之numpy之方差numpy.var

热门文章

  1. 计算机打音乐歌谱成都,赵雷成都的曲谱
  2. zlib deflate gzip区别
  3. JS验证通过之后才提交表单
  4. smart svn破解
  5. tolua学习资料汇总贴
  6. 微信公众号开发(一)——测试账号申请
  7. hypervisor详解
  8. SQL每日一题(20210901)如果员工的【入职日期】是当月15号后,则该员工的【社保缴纳月份】为【入职日期】的次月
  9. 穷举字符串c语言,穷举密码算法
  10. 2-3 /电脑屏幕录制神器!- Bandicam 满足您对录屏功能的所有幻想!