【Java】设计模式之保护性暂停

设计模式之保护性暂停

Guarded Suspension,这个设计模式,主要用在一个线程等待另一个线程的执行结果(发请求等待响应)

  • 有一个结果需要从一个线程传递到另一个线程,传递只进行一次,用设计模式保护性暂停。

  • 如果有结果不断从一个线程到另一个线程那么可以使用另一个设计模式消息队列(之后的知识)

  • JDK 中, join 的实现、 Future 的实现,采用的就是此模式

  • 因为要等待另一方的结果,因此归类到同步模式

想要让一个线程等待另一个线程的执行结果,可以让这两个线程都关联上同一个 Guarded 0bject保护对象,让对象的管程的waitset来充当通知的桥梁,使用对象的wait()/notify()方法来进行通知。

结果如何从线程2传到线程1?其实保护对象由开发者创建,它的属性就是response。线程1对该对象加锁并执行wait()方法,线程1首先执行陷入阻塞。线程2也对保护对象加锁,当它执行完毕之后,将结果记录在保护对象的response之中然后执行notifyAll()方法唤醒线程1。线程1被唤醒,它就可以从保护对象的response属性中拿到线程2处理的结果。


改进:

如果要多个类之间进行通信,使用保护对象不是很方便。 因此设计一个用来解耦的中间类,这样不仅能够解耦【结果等待者】和【结果生产者】,还能够同时支持多个任务的管理。

注意:在这种情况下,结果等待者和结果生产者还是一一对应的。如果结果等待者和结果生产者是多对多的关系,要用到另一种设计模式——生产者/消费者。

在这里插入图片描述

需要创建一个保护对象的管理器来管理多个保护对象。

package org.example;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Hashtable;
import java.util.Map;/*** @author xcy*/public class Main {static Logger logger= LoggerFactory.getLogger("test");public static void main(String[] args) throws InterruptedException {//结果等待者//这个for循环创建了5个保护对象,创建对象的方法确实是原子性的,但是这5个对象的保护对象不会和线程序号一致//因为5个线程并不是循环new出一个立刻就执行一个,线程的启动会有延迟//比如说线程1、2、3、4、5,并不是按照12345的顺序启动,会随机启动,所以最后线程名和创建出保护对象名称并不一致//如果想要让保护对象的序号与线程一致,要根据当前线程的序号来创建保护对象,而不是循环计数for (int i = 0; i < 5; i++) {int finalI=i;new Thread(() -> {GuardedObject guardedObject = GuardedObjectManager.createGuardedObject();logger.debug("开始等待结果,线程的保护对象为:"+guardedObject.getId());guardedObject.waitResult();logger.debug("等到结果:" + guardedObject.getResponse());},"t"+finalI).start();}Thread.sleep(1000);//结果生产者for (int i = 5; i < 10; i++) {int finalI = i;new Thread(() -> {GuardedObject guardObject = GuardedObjectManager.getGuardObject(finalI - 5);System.out.println(Thread.currentThread()+"获得保护对象:"+guardObject);guardObject.complete(finalI);},"t"+finalI).start();}}
}/*** 保护对象,用于两个线程之间的通信*/
class GuardedObject {private Integer id;private Object response;public GuardedObject(Integer id) {this.id = id;}/*** 拥有该对象锁的线程释放对象锁,进入等待队列*/public synchronized Object waitResult() {while (response == null) {try {this.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}return this.response;}/*** 唤醒该对象等待队列中的线程*/public synchronized void complete(Object response) {System.out.println("线程"+Thread.currentThread()+"返回结果"+response);this.response = response;this.notifyAll();}public Integer getId() {return id;}public Object getResponse() {return response;}@Overridepublic String toString() {return "GuardedObject{" +"id=" + id +'}';}
}/*** 用来管理GuardedObject*/
class GuardedObjectManager {private static int id;/*** 由于hashmap是线程不安全的,所以用hashtable保证put和get的原子性*/public static Map<Integer, GuardedObject> map = new Hashtable<>();public synchronized static GuardedObject createGuardedObject() {System.out.println(Thread.currentThread()+":"+id);GuardedObject guardedObject = new GuardedObject(id);map.put(id, guardedObject);id++;System.out.println(Thread.currentThread()+":"+id);return guardedObject;}public static GuardedObject getGuardObject(int id) {return map.get(id);}
}

结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/605564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何平衡 SEO 与思想领导力内容战略

曾几何时&#xff0c;SEO 是一个肮脏的词&#xff0c;与 "黑帽 "操作有关&#xff0c;他们通过操纵排名来达到邪恶的目的。现在&#xff0c;有些人认为这是一种炼金术的转化&#xff1a;锡变金&#xff0c;内容变客户。 实际上&#xff0c;这两种说法都不正确。 没…

2023检索增强生成技术(RAG)研究进展

一、前言 在过去的一两年里&#xff0c;人工智能领域目睹了检索增强生成技术&#xff08;RAG&#xff09;的迅猛发展&#xff0c;这种技术结合了强大的语言模型与信息检索系统&#xff0c;以期在复杂的问题解决和信息处理任务中提供更加精确和深入的答案。正是这种对前沿科技的…

振弦采集仪在桥梁结构监测中的应用研究

振弦采集仪在桥梁结构监测中的应用研究 振弦采集仪在桥梁结构监测中的应用研究是指利用振弦采集仪对桥梁结构进行监测和数据采集的研究。振弦采集仪是一种能够实时监测桥梁结构振动情况的设备&#xff0c;通过采集桥梁上的振弦传感器获取振动数据&#xff0c;并将数据传输到监…

【数据库分库分表思路】

一、数据切分介绍 关系型数据库本身比较容易成为系统瓶颈&#xff0c;单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后&#xff0c;由于查询维度较多&#xff0c;即使添加从库、优化索引&#xff0c;做很多操作时性能仍下降严重。此时就要考虑对其进…

vue+element弹窗内---下拉框定位问题解决(方法之一)

问题: 加了 :popper-append-to-body"false" 这个属性也不好用时 可以试试这个 解决: 第一步: 找到el-select标签添加(popper-class"popperClass")属性-----如下图 第二步:在css中添加如下代码即可 ::v-deep .popperClass{ top:auto !important; }

静态网页设计——个人图书馆(HTML+CSS+JavaScript)(dw、sublime Text、webstorm、HBuilder X)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1VN4y1q7cz/?vd_source5f425e0074a7f92921f53ab87712357b 源码&#xff1a;https://space.bilibili.co…

python总结-生成器与迭代器

生成器与迭代器 生成器生成器定义为什么要有生成器创建生成器的方式一(生成器表达式) 创建生成器的方式二(生成器函数)生成器函数的工作原理总结 迭代器概念可迭代对象和迭代器区别for循环的本质创建一个迭代器 动态添加属性和方法运行过程中给对象、类添加属性和方法types.Met…

kafka之消费者(Consumer)

1、kafka消费者消费方式 kafka 的消费者&#xff08;Consumer&#xff09;采用 pull 的方式主动从 broker 中拉取数据&#xff0c;这种不足之处会有&#xff1a;当 broker 中没有消息时&#xff0c;消费者会不断循环取数据&#xff0c;一直返回空数据。 2、消费者组 Consumer…

【数据结构】平衡二叉树

导语 对于二叉搜索树 而言&#xff0c;它的 增、 删 、 改 、 查 的时间复杂度为 O() ~ O(n) 。原因是最坏情况下&#xff0c;二叉搜索树会退化成 线性表 。换言之&#xff0c;树的高度决定了它插入、删除和查找的时间复杂度。 为了对上述缺点进一步优化&#xff0c;设计了一…

APM32F035有感矢量控制方案

一、先来几句废话 首先这两年公司越来越多的开始使用国产的MCU&#xff0c;用过GD32、AT32、APM32等等&#xff0c;目前稳定使用的是APM32,包括身边朋友工作室&#xff0c;也开始从TI、STM、NXP换成APM32。上个月有幸拿到APM32F035电路控制板&#xff0c;非常感谢面包板社区提供…

实战环境搭建-linux下安装tomcat

安装tomcat Index of /dist/tomcat/tomcat-9/v9.0.8/bin 下载apache-tomcat-9.0.8.tar.gz,可以使用wget; 2、将压缩包tar -zxvf apache-tomcat-9.0.8.tar.gz解压到/home/tomcat 3、修改环境变量 vi /etc/profile export JAVA_HOME=/home/java/jdk1.8.0_221 export JRE_HO…

sublime如何取消运行代码状态

sublime如何取消运行代码状态 解决方案待续、更新中 解决方案 1 顶部取消: 工具-----取消编译 这个看自己编译器sublime取消编译是否可用,可用则用 ,否则使用下面方法 2 底部栏取消–如图所示: 取消成功: 待续、更新中 ————————————————————— 以上就…

基于php应用的文件管理器eXtplorer部署网站并内网穿透远程访问

文章目录 1. 前言2. eXtplorer网站搭建2.1 eXtplorer下载和安装2.2 eXtplorer网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1. 前言 通过互联网传输文件&#xff0c;是互联网最重要的应用之一&#xff0c;无论是…

7.数据转换、格式化、校验

日期字符串格式的表单参数,提交后转换为 Date 类型 <!-- 解决问题: 1.数据类型转换 2.数据格式 3.数据校验 --> BirthDay :<form:input path="birthDay"/>Employee 类中增加日期类型属性: //关于类型转换 private Date birthDay ;数据绑定流程原理 …

Qt QWidget窗口基类

文章目录 1 QWidget介绍2 如何显示 QWidget窗口2.1 新建基于QWidget的窗口类2.2 再添加一个QWidget窗口类2.3 显示新添加的 QWidget窗口 3 常用的属性和方法3.1 窗口位置3.2 窗口大小3.3 窗口标题3.4 窗口图标3.5 资源文件 4 实例 1 QWidget介绍 Qt 中的常用控件&#xff0c;比…

什么是CDN,优势在哪里

随着互联网的普及和用户需求的多样化&#xff0c;网站的速度和稳定性已经成为影响用户体验的关键因素。CDN加速作为解决这一问题的有效手段&#xff0c;正逐渐受到业界的广泛关注。 为什么说对网站这一块起到这么关键性的作用呢&#xff1f;它的优势在哪&#xff1f; 1.提升网…

【机器学习】卷积神经网络(五)-计算机视觉应用

七、应用-计算机视觉 7.1 人脸检测 DenseBox\Femaleness-Net\MT-CNN\Cascade CNN 介绍 VJ框架的分类器级联用于卷积网络 用于人脸检测的紧凑卷积神经网络级联 问题&#xff1a;作者希望实时检测高分辨率视频流中的正面&#xff0c;由于人脸图像和背景的多样性和复杂性&#xff…

【MIdjourney】图像角度关键词

本篇仅是我个人在使用过程中的一些经验之谈&#xff0c;不代表一定是对的&#xff0c;如有任何问题欢迎在评论区指正&#xff0c;如有补充也欢迎在评论区留言。 1.侧面视角(from side) 侧面视角观察或拍摄的主体通常以其侧面的特征为主要焦点&#xff0c;以便更好地展示其轮廓…

02. Eureka、Nacos注册中心及负载均衡原理

01小节中订单服务远程调用用户服务案例实现了跨服务请求&#xff0c;在微服务中一个服务可能是集群部署的&#xff0c;也就是一个服务有多个实例&#xff0c;但是我们在调用服务时需要指定具体的服务实例才能调用该服务&#xff0c;在集群模式下&#xff0c;服务地址应该写哪个…

1.3号io网络

文件IO 1.文件IO是基于系统调用 2.程序每进行一次系统调用&#xff0c;就会从用户空间向内核空间进行一次切换&#xff0c;执行效率较慢 3.目的&#xff1a;由于后期进程间通信&#xff0c;如管道、套接字通信&#xff0c;都使用的是文件IO&#xff0c;所以引入文件IO操作的…