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

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

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

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

相关文章

C++流的基本概念

在C语言中,数据的输入和输出(简写为I/O)包括对标准输入设备键盘和标准输出设备显示器、对在外存磁盘上的文件和对内存中指定的字符串存储空间(当然可用该空间存储任何信息)进行输入输出这三个方面。对标准输入设备和标…

天哪,flash cs4可以使动态文本旋转了

天哪,flash cs4可以使动态文本旋转了. 只要使用rotationZ属性即可。 这可是解决了一个跨世纪的问题,爽爽爽。 啊哈哈哈。 这是测试源代码。 var rTextField:TextFieldnewTextField();var textFormat:TextFormatnewTextFormat();rTextField.text"…

Java编译过程(传送门)

我不是要做一门编程语言,了解这个对我现在的工作也没什么帮助,纯粹好奇而已。 传送门转载于:https://www.cnblogs.com/flying607/p/10481239.html

Linux 系统如何调整时区和时间

比如我要吧机器调成太平洋时区,那么我可以输入以下的命令,我们创建一个Link文件来指明是Pacific Time: cd /etc/ rm –r localtime sudo ln -s /usr/share/zoneinfo/US/Pacific localtime 调节完时区之后,接下来就是设置时间&a…

C语言typedefine 和define的区别

define : 宏定义,在预编译阶段就进行处理,简单的字符串代换,typedefine: 编译时进行处理,不是简单的替换,而是对类型说明符的重新命名。被命名的标识符具有类型说明的功能,代码说明#…

博客园“图灵杯”第3届博问大赛比赛结果

经过近一个月的激烈角逐,博客园“图灵杯”第三届博问大赛已圆满结束。获奖园友分别是: 一等奖:邀月(奖励图灵图书4本) 二等奖:Kinglee、邢少(奖励图灵图书2本) 三等奖:Gr…

Objective-C优缺点

优点: 1:Category,使用category可以在不改变原来类的同时为类增加新的方法或者重写原来类的方法实现(使用runtime方法还可以在分类中实现方法交换和添加属性操作) 2:运行时 动态识别,动态添加方…

C++输入一个字符串,去掉这个字符串中出现次数最少的字符 例如: 输入:abcabbc 输出:bbb

统计字符的个数&#xff0c;记录出现最少的字符&#xff0c;然后再输出#include <iostream>using namespace std;int main() {char str[100];cin >> str;// 统计字符大小int count[256] {0};char *p str;while (*p ! \0){count[*p];p;}// 记录出现最少的字符 出现…

Jmeter测试监控 Summary Report界面

Jmeter测试监控 Summary Report界面 这几天使用了JMeter测试数据库在进行点查询时的读写性能&#xff0c;从网上找到了该篇文章用于备份。 所有数据写入一个文件&#xff1a;保存测试结果到本地。 文件名&#xff1a;指定保存结果。 仅日志错误&#xff1a;仅保存日志中报错…

我的LINUX学习之路之二十一之web服务器简单搭建

今天说说如何搭建HTTP服务器&#xff01; 目的&#xff1a; 使用“多IP地址”方法实现多个网站。 使用“主机头名”方法实现多个网站。 使用“多端口”方法实现多个网站。 这回用图形界面来&#xff0c;不用说&#xff0c;先来看安装软件&#xff01; System-Administation-添加…

公务员级别分类

公务员领导职务层次与级别的对应关系 (一)国家级正职&#xff1a;一级(二)国家级副职&#xff1a;四级至二级(三)省部级正职&#xff1a;八级至四级(四)省部级副职&#xff1a;十级至六级(五)厅局级正职&#xff1a;十三级至八级(六)厅局级副职&#xff1a;十五级至十级(七)县处…

iOS性能优化篇 —— 耗电优化总结

手机App耗电的主要来源有以下四个因素&#xff1a; CPU处理&#xff0c;Processing网络&#xff0c;Networking定位&#xff0c;Location图像&#xff0c;Graphics耗电优化最终目的&#xff1a;通过尽可能降低CPU、GPU功耗来降低手机电量消耗。 尽可能少用定时器&#xff1b;优…

Versant 对象型数据库

引用&#xff1a;http://www.versant.com.cn/vision.aspx 对象数据库&#xff0c;可能比传统数据库快几十倍&#xff0c;收费&#xff0c;等测试 在几十万的数据库&#xff0c;找任一两个数据关系&#xff0c;不用比较

找出一个数组中唯一一个出现2次的数字

找出一个数组中唯一一个出现2次的数字&#xff0c;不清楚是不是LeetCode上的题。本人默认是LeetCode上的题。 一个数组中有N个数字&#xff0c;但是只有一个数字出现了2次&#xff0c;其他的数字均不相同。这种问题一般应该采用hash方法实现。 让所有的数字都放到一个unorder…

c语言fgets函数的用法

fgets()函数用于从文件流中读取一行或指定个数的字符&#xff0c;其原型为&#xff1a;char * fgets(char * string, int size, FILE * stream);参数说明&#xff1a; string为一个字符数组&#xff0c;用来保存读取到的字符。 size为要读取的字符的个数。如果该行字符数大于si…

.Net 中的反射(查看基本类型信息) - Part.2

转自&#xff1a;http://www.cnblogs.com/JimmyZhang/archive/2008/02/17/1071372.html 反射概述 和Type类 1.反射的作用 简单来说&#xff0c;反射提供这样几个能力&#xff1a;1、查看和遍历类型(及其成员)的基本信息和程序集元数据(metadata)&#xff1b;2、迟绑定(Late-Bin…

clientHeight , scrollHeight , offsetHeight之间的区别及兼容方案

clientHeight , scrollHeight , offsetHeight之间的区别及兼容方案&#xff1a;https://www.cnblogs.com/nanshanlaoyao/p/5964730.html height、clientHeight、scrollHeight、offsetHeight区别 &#xff1a;https://www.cnblogs.com/yi-mi-yangguang/p/6211305.html 转载于:h…

动手写了一个12306插件 chrome浏览器

2019独角兽企业重金招聘Python工程师标准>>> 小生是今年毕业来上海参加工作的一位很普通的java web程序员&#xff0c;后经人介绍转到SAP方向。 以前大学离家相对比较近&#xff0c;都是坐汽车回家的&#xff0c;平常都不是高峰期坐火车&#xff0c;使用12306倒是非…

行列存储方式比较

原文链接&#xff1a;https://blog.csdn.net/vagabond6/article/details/79555282 写入&#xff1a; 行存储的写入是一次完成&#xff0c;数据的完整性因此可以确定。 列存储需要把一行记录拆分成单列保存&#xff0c;写入次数明显比行存储多。 行存储在写入上占有很大的优势 …

c/c++整理--c++面向对象(1)

一、描述面向对象技术的基本概念面向对象是指按人们认识客观世界的系统思维方式&#xff0c;采用基于对象&#xff08;实体&#xff09;的概念建立模型&#xff0c;模拟客观世界分析、设计、实现软件的方法&#xff0c;包括类、对象、消息以及类的特性等方面的内容。类&#xf…