【设计模式】JAVA Design Patterns——Monitor(监视器模式)

🔍目的


主要目的是为多个线程或进程提供一种结构化和受控的方式来安全地访问和操作共享资源,例如变量、数据结构或代码的关键部分,而不会导致冲突或竞争条件。

🔍解释


通俗描述

监视器模式用于强制对数据进行单线程访问。 一次只允许一个线程在监视器对象内执行代码。

维基百科

在并发编程(也称为并行编程)中,监视器是一种同步构造,它允许线程具有互斥性和等待(阻止)特定条件变为假的能力。 监视器还具有向其他线程发出信号通知其条件已满足的机制。

程序示例

考虑有一家银行通过转账方式将钱从一个帐户转移到另一个帐户。 它是同步意味着只有一个线程可以访问此方法,因为如果许多线程访问它并在同一时间将资金从一个帐户转移到另一个帐户,则余额会发生变化!

class Bank {

     private int[] accounts;
     Logger logger;
 
     public Bank(int accountNum, int baseAmount, Logger logger) {
         this.logger = logger;
         accounts = new int[accountNum];
         Arrays.fill(accounts, baseAmount);
     }
 
     public synchronized void transfer(int accountA, int accountB, int amount) {
         if (accounts[accountA] >= amount) {
             accounts[accountB] += amount;
             accounts[accountA] -= amount;
             logger.info("Transferred from account :" + accountA + " to account :" + accountB + " , amount :" + amount + " . balance :" + getBalance());
         }
     }

getBalance 始终返回总金额,并且每次转账后总金额应相同 

     private synchronized int getBalance() {
         int balance = 0;
         for (int account : accounts) {
             balance += account;
         }
         return balance;
     }
 }

🔍类图


🔍适用场景

监视器设计模式应该用于具有需要由多个线程或进程同时访问和操作的共享资源的情况。 此模式在需要同步以防止竞争条件、数据损坏和不一致状态的情况下特别有用。 以下是您应该考虑使用监视器模式的一些情况:

  1. 共享数据:当您的应用程序涉及需要由多个线程访问和更新的共享数据结构、变量或资源时。 监视器确保一次只有一个线程可以访问共享资源,从而防止冲突并确保数据一致性。

  2. 关键部分:当您有代码的关键部分一次只需要由一个线程执行时。 关键部分是操作共享资源的代码部分,并发访问可能会导致问题。 监视器有助于确保在任何给定时间只有一个线程可以执行关键部分。

  3. 线程安全:当您需要确保线程安全而不是仅仅依赖锁和信号量等低级同步机制时。 监视器提供了封装同步和资源管理的更高级别的抽象。

  4. 等待和发信号:当您遇到线程需要等待满足某些条件才能继续操作时。 监视器通常包含线程等待特定条件以及其他线程在满足条件时通知它们的机制。

  5. 死锁预防:当您希望通过提供结构化方式来获取和释放共享资源上的锁来防止死锁时。 监视器通过确保资源访问得到良好管理来帮助避免常见的死锁情况。

  6. 并发数据结构:当您实现并发数据结构(例如队列、堆栈或哈希表)时,多个线程需要操作该结构,同时保持其完整性。

  7. 资源共享:当多个线程需要共享有限的资源时,例如连接数据库或访问网络套接字。 监视器可以帮助以受控方式管理这些资源的分配和释放。

  8. 改进可维护性:当您想要将同步逻辑和共享资源管理封装在单个对象中时,改进代码组织并使并发相关代码更容易推理。

🔍Ending


需要注意的是,监视器模式可能并不最适合所有并发场景。 在某些情况下,其他同步机制(例如锁、信号量或并发数据结构)可能更合适。 此外,现代编程语言和框架通常提供更高级别的并发结构,抽象出低级别同步的复杂性。

在应用监视器模式之前,建议彻底分析应用程序的并发需求,并选择最适合您需求的同步方法,同时考虑性能、复杂性和可用语言功能等因素。


希望本文能够帮助读者更深入地理解监视器模式,并在实际项目中发挥其优势。谢谢阅读!


希望这份博客草稿能够帮助到你。如果有其他需要修改或添加的地方,请随时告诉我。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于java的CRM客户关系管理系统(六)

目录 5.3 表现层设计 5.3.1 模型层(M) 5.3.2 视图层(V) 5.3.3 控制层(C) 5.4 系统主要功能模块的实现 5.4.1 登录功能的实现 5.4.2 客户管理的实现 5.5 本章小结 参考文献 前面内容请移步 基于java…

基本元器件 - 电感与磁珠

电感 电感的选型 体积大小电感值所在工作频率开关频率下的电感值为实际需要的电感值线圈的直流阻抗(DCR)越小越好工作电流应降额至额定饱和电流的 0.7 倍以下,额定 rms 电流;交流阻抗(ESR)越小越好&#…

10 款在线剽窃检查的 [免费工具]

剽窃或抄袭他人文章而不注明出处,几乎在所有领域都被认为是有害的。然而,学术界最痛恨这种行为。抄袭是对学术诚信的最大威胁。这就是为什么每个教育机构总是希望学生提交无抄袭的作业。 然而,有时学生无意中剽窃了他人的作业,直…

【软件开发】Java学习路线

本路径视频教程均来自尚硅谷B站视频,Java学习课程我已经收藏在一个文件夹下,B站文件夹同时会收藏其他Java视频,感谢关注。指路:https://www.bilibili.com/medialist/detail/ml3113981545 2024Java学习路线(快速版&…

命名空间,缺省参数和函数重载

前言:本文章主要介绍一些C中的小语法。 目录 命名空间 namespace的使用 访问全局变量 namespace可以嵌套 不同文件中定义的同名的命名空间可以合并进一个命名空间,并且其中不可以有同名的变量 C中的输入和输出 缺省参数(默认参数&#…

超越Devin!姚班带队,他们创大模型编程新世界纪录

超越Devin!SWEBench排行榜上迎来了新玩家—— StarShip CodeGen Agent,姚班带队初创公司OpenCSG出品,以23.67%的成绩获得全球第二名的成绩。 同时创造了非GPT-4o基模的最高纪录(SOTA)。 我们都知道,SWEBe…

for深入学习

目录 练习&#xff1a; 例1&#xff1a; 求解0-100中整除3的数有哪些 例2&#xff1a; 求0-100中含数字9个个数 作业&#xff1a; 练习&#xff1a; 例1&#xff1a; 求解0-100中整除3的数有哪些 代码&#xff1a; #include<stdio.h> int main() {printf("整…

JAVAEE之网络初识_协议、TCP/IP网络模型、封装、分用

前言 在这一节我们简单介绍一下网络的发展 一、通信网络基础 网络互连的目的是进行网络通信&#xff0c;也即是网络数据传输&#xff0c;更具体一点&#xff0c;是网络主机中的不同进程间&#xff0c;基于网络传输数据。那么&#xff0c;在组建的网络中&#xff0c;如何判断到…

深入理解计算机系统 第三版 中文版 图5-27 p371 错漏

中文版 英文版 对照 可以看出错漏 这本书中文版很多错漏,可以配合英文版查正,不过英文版也很多错漏,所以不用太相信书本.要根据自己的理解来.

TDengine为物联网而生的大数据平台

TDengine为物联网而生的大数据平台 物联网背景 技术支撑 应用落地 未来趋势

【动手学深度学习】softmax回归从零开始实现的研究详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 softmax回归的从零开始实现 &#x1f30d;3.2 基础练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 理解softmax回归的原理和基本实现方式&#xff1b;学习…

算法金 | 再见,支持向量机 SVM!

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 一、SVM概述 定义与基本概念 支持向量机&#xff08;SVM&#xff09;是一种监督学习模型&#xff0c;用于解决分类和回归问题。它的核…

Streamsets-JDBC模式offset变化逻辑和如何向下传递offset

Streamsets的版本为3.16.0 离线版 offset在jdbc模式中起到非常关键的作用&#xff0c;是滚动查询的基础&#xff0c;offset的准确直接影响数据同步的质量。 本文主要分享一下JDBC Query Consumer中的offset&#xff0c;包括变化逻辑、存储方式、处理器如何获取到最新的offset。…

如何在QGIS中加载MapBox图源

在设计行业中需要多风格地图的调用&#xff0c;不管是规划、建筑设计还是景观&#xff0c;分析图的工作量都大&#xff0c;有好的底图&#xff0c;会事半功倍。 针对不同项目&#xff0c;会选择不同配色的底图&#xff0c;以便让设计内容中的呈现足够清晰。 这里就来分享一个…

如何在自己的电脑上添加静态路由

1.任务栏搜索powershell 选择以管理员身份运行 2.输入 route add -p (永久) 目的网络地址例如192.168.10.0 mask 255.255.255.0&#xff08;子网掩码&#xff09;192.168.20.1&#xff08;下一跳地址&#xff09;。回车即可生效

238.除以自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。 题目数据保证数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度内完…

网络编程(六)

网络编程&#xff08;六&#xff09; 广播&组播广播步骤 组播步骤 广播&组播 广播 是一种基于1发送多接收的模型 &#xff08;发送方和接收方&#xff09; 广播是在局域网内实现的&#xff08;发送到广播地址上的消息是会被局域网内同网段的所有主机进行接收&#xf…

[Redis]Set类型

集合类型也是保存多个字符串类型的元素的&#xff0c;但和列表类型不同的是&#xff0c;集合中 1&#xff09;元素之间是无序的 2&#xff09;元素不允许重复 一个集合中最多可以存储2^32-1个元素。 Redis 除了支持集合内的增删查改操作&#xff0c;同时还支持多个集合取交…

深入探讨ChatGPT API中的Tokens计算方式和计算库

引言 在现代人工智能应用中&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术无疑是最受关注的领域之一。OpenAI推出的ChatGPT&#xff0c;作为一种先进的对话模型&#xff0c;已经在多个领域展示了其强大的语言生成能力。为了更好地使用ChatGPT API&#xff0c;理解其…

操作系统(3) 处理机调度

目录 一、处理机调度概述 1.基本准则 &#xff08;1&#xff09;CPU利用率 &#xff08;2&#xff09;系统吞吐量 &#xff08;3&#xff09;周转时间 &#xff08;4&#xff09;等待时间 &#xff08;5&#xff09;响应时间 2.进程调度方式 &#xff08;1&#xff0…