4.3线程安全接口(Thread-Safe Interface)

1.问题

多线程组件通常包括多个可被公共访问的接口方法以及可以改变组件状态的私有方法。为了避免出现竞争条件,可以使用一个组件内部的锁对访问其状态的接口方法调用串行化。尽管当每个方法都自包容的时候,这种设计方法能很好地工作。但组件方法可能会相互调用完成计算任务。如果是这样,在多线程组件中有以下几个强制条件尚未解决,它们使用了错误的组件间方法调用的设计方法:

1)应该使线程安全组件避免“自死锁”。当一个组件方法在该组件中获得一个非递归锁,然后调用试图获得同一个锁的另一个组件方法时,会发生自死锁。

2)为了避免出现对组件状态的竞争条件等情况,应该使线程安全组件具有最小的加锁开销。如果为避免上面介绍的自死锁问题而选择一个递归组件锁,由于组件间方法调用多次获得和释放锁,而会产生不必要的开销。

2.解决方案

按照以下两个约定将处理组件间方法调用的所有组件初始化:

1)接口方法检查。所有接口方法(如C++公有方法)应该只获得/释放组件锁,在组件的“边缘”进行同步检查。获得一个锁后,接口方法立即转发给一个实现方法,后者执行实际的方法功能。实现方法返回后,接口在将控制返回给调用者之前释放该锁。

2)实现方法信任。只有被接口方法调用,实现方法(如C++的私有或保护方法)才能完成它们的任务。因此它们相信只有在获得锁后才会调用它们,它们本身不应该获得或释放锁。实现方法也不应该“向上”调用接口方法,因为接口要获得锁。

3.实现

1)确定接口和相应的实现方法。接口方法定义组件的公共API,为每个接口方法对应地定义一个实现方法。

2)对接口和实现方法进行编程。

4.结论

优点:

1)提高了健壮性。由于使用组件间方法调用,该模式可以避免自死锁。

2)改善了性能。该模式确保在必要时才获得或释放锁。

3)简化了软件。将加锁和功能特性问题分开,可以使加锁和功能特性得到简化。

不足:

1)增加间接的和额外的方法。

2)潜在的死锁。

3)潜在的误用。

4)潜在的开销。

4.4双检查加锁优化(double-checked locking optimization)

1.问题

串行化加锁方法对于只要求执行一次初始化的对象或组件是不合适的,例如Singleton中的临界区代码在其初始化阶段必须执行一次。但是对Singleton的每个方法调用都要获取和释放互斥锁,从而过多地增加了开销,为避免这些开销,并发应用的程序员可能转而使用全局变量而不是单件模式。不过这种解决方案有两个缺点:

·可移植性不好。因为通常没有指定在不同文件中定义的全局对象被构造的顺序。

·资源的浪费。因为即使不使用全局变量,也要产生全局变量。

2.解决方案

引入一个标志,表示在获得一个保证临界区的锁之前确定是否需要执行该临界区。如果不需要执行该代码,就跳过该临界区,从而避免了不必要的加锁开锁。在临界区内增加相同的标志检测,表示进入临界区后是否需要初始化资源,从而避免了资源被多次初始化。

3.实现

1)确定要仅执行一次的临界区。该临界区进行的操作(如初始化逻辑)在程序中仅执行一次。

2)实现加锁逻辑。加锁逻辑对只执行一次的临界区代码的访问串行化。

3)实现首次进入(first-time-in)标志。该标志表示临界区是否被执行过。

4.结论

优点:

1)使加锁开销最小。

2)防止竞争条件。

不足:

1)非原子指针或集成赋值语义。

2)多处理器缓存的连贯性。

3)额外的互斥使用。

转载于:https://www.cnblogs.com/pennant/archive/2012/09/24/2698956.html

《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(13)--- 线程安全接口和双检查加锁优化...相关推荐

  1. 《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(3)--- 服务访问和配置模式...

    服务访问和配置模式 包装器外观(Wrapper Facade)设计模式把现有的非面向对象的API所提供的函数和数据,封装在更加简洁的.健壮的.可移植的.可维护的和内聚的面向对象的类接口里面.常常应用包 ...

  2. 《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(7)--- 事件处理模式与反应器...

    事件处理模式 使用反应器(Reactor)结构化模式,事件驱动的应用可以多路分解并分配从一个或者多个客户机发送给应用的服务请求.反应器模式引入的结构"逆转"了应用中的控制流,这就是 ...

  3. 《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(12)--- 策略化加锁...

    4.2策略化加锁(Strategized Locking) 1.问题 运行在多线程环境中的组件必须保护其临界区不被客户机并发访问.同步机制与组件功能的集成需要解决以下两个强制条件: 1)不同的应用程序 ...

  4. 《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(17)--- 领导者/追随者...

    5.4领导者/追随者(Leader/Follower) 1.问题 多线程是实现并发处理多事件的应用程序的一种常用技术.然而,很难实现高性能的多线程服务器应用程序.这些应用程序通常处理大量同时到达的多类 ...

  5. 面向模式的软件体系结构(卷1-5

    面向模式的软件体系结构(卷1-5 [一日养生24法].宋爱莉.插图版.pdf: http://www.t00y.com/file/60331740 [一桶金]--颠覆传统赚钱方式的系统创富法则.艾莫. ...

  6. 面向模式的软件体系结构

    面向模式的软件体系结构,卷2,详细介绍并发网络服务器 C 语言常见问题集 转载于:https://www.cnblogs.com/unixshell/p/3825490.html

  7. 《软件建模与设计: UML、用例、模式和软件体系结构》一一2.10 UML扩展机制

    本节书摘来自华章计算机<软件建模与设计: UML.用例.模式和软件体系结构>一书中的第2章,第2.10节,作者:(美)Hassan Gomaa,更多章节内容可以访问云栖社区"华章 ...

  8. 《软件建模与设计: UML、用例、模式和软件体系结构》一一3.1 软件生存周期模型...

    本节书摘来自华章计算机<软件建模与设计: UML.用例.模式和软件体系结构>一书中的第3章,第3.1节,作者:(美)Hassan Gomaa,更多章节内容可以访问云栖社区"华章计 ...

  9. 《软件建模与设计: UML、用例、模式和软件体系结构》一一3.2 设计验证和确认...

    本节书摘来自华章计算机<软件建模与设计: UML.用例.模式和软件体系结构>一书中的第3章,第3.2节,作者:(美)Hassan Gomaa,更多章节内容可以访问云栖社区"华章计 ...

最新文章

  1. 【No.5 类型转换导致的错误】
  2. 【好资源】473页斯坦福数学基础:《应用线性代数》(附pdf和ppt下载)
  3. leetcode 遇到的问题
  4. BugKuCTF 杂项 come_game
  5. 喜马拉雅xm格式转化mp3_怎样让mp3录音转文字?
  6. HEVC/H265 解码图表,请对照代码看。
  7. 《人人都是产品经理》读后感
  8. 命令行_Laravel-admin artisan 命令行脚本使用
  9. php 调试 500,利用WordPress开发者调试模式解决PHP500内部服务器错误 | 骤雨打新荷...
  10. 【Arcpy】Python in ArcGIS
  11. C语言实现数字串转数字
  12. Struts2升级版本至2.5.10,高危漏洞又来了
  13. 浅谈公路工程项目管理的发展趋势
  14. CSDN各产品线月度NPS分析报告新鲜出炉【2021年7月】
  15. pyspark groupby 后将遍历的每一行转成pandas df
  16. 36 岁开发者应聘被拒?这 3 位 50 岁程序员的生存秘籍送给你!
  17. 电商平台快递物流解决方案
  18. net的曲线救国,学习路径 MVVM (一)
  19. python--format
  20. 云存储毕业设计基于SSM个人网盘系统设计与实现.rar(论文+程序源码)

热门文章

  1. (十九)TCPIP面试宝典-进入大厂必备总结(上)
  2. (五)深入浅出TCPIP之TCP流量控制
  3. LeetCode - Easy - 637. Average of Levels in Binary Tree
  4. python两个for循环为什么第二个循环里值不变_两个for循环,第二个只在第一个迭代python上执行...
  5. clion在使用sqlite3的时候,显示Undefined symbols for architecture x86_64错误的解决办法
  6. C++学习 优雅的实现对象到文件的序列化/反序列化 关键字serialize
  7. 算法入门篇三 详解桶排序和整理排序知识 堆的相关操作 补充 不完整
  8. codeforces 791A-C语言解题报告
  9. 离合器半联动点的判断和技巧 为您支招
  10. 面试问题汇总 精选 分析 解答 职业规划 part 4