线程同步 线程安全_同步装饰器来替换线程安全类

线程同步 线程安全

您知道什么是线程安全吗? 如果没有,下面是一个简单的示例。 所有类都必须是线程安全的,对吗? 并不是的。 其中一些必须是线程安全的? 又错了。 我认为它们都不必是线程安全的,而它们都必须提供同步的装饰器。

阿拉丁(1992),罗恩·克莱门茨和约翰·马斯克

让我们从一个示例开始(顺便说一下,它是mutable ):

class Position {private int number = 0;@Overridepublic void increment() {int before = this.number;int after = before + 1;this.number = after;}
}

您如何看待-它是线程安全的吗? 该术语指的是当同时由多个线程使用时,此类的对象是否将正确运行。 假设我们有两个线程在同一个对象position ,并在完全相同的时刻调用其方法increment()

我们期望两个线程结束时整数的number等于2,因为它们每个都会递增一次,对吗? 但是,这极有可能不会发生。

让我们看看会发生什么。 在两个线程中,启动时, before等于0 。 然后after将设置为1 。 然后,两个线程会做this.number = 1 ,我们将结束与1number ,而不是预期2 。 看到问题了吗? 在设计中存在此类缺陷的类不是线程安全的

最简单,最明显的解决方案是使我们的方法synchronized 。 这样可以保证无论有多少线程同时调用它,它们都会按顺序而不是并行进行:一个线程接一个线程。 当然,这将花费更长的时间,但是它将防止该错误的发生:

class Position {private int number = 0;@Overridepublic synchronized void increment() {int before = this.number;int after = before + 1;this.number = after;}
}

保证无论有多少线程都不会中断的类称为线程安全

现在的问题是:我们是否必须使所有类都成为线程安全的,或者只使其中某些类成为线程安全的? 使所有类都无错误似乎更好,对吗? 为什么有人想要一个可能在某个时候破裂的物体? 好吧,不完全是。 请记住,涉及性能问题; 我们通常没有多个线程,并且我们始终希望我们的对象尽可能快地运行。 线程间同步机制肯定会使我们慢下来。

我认为正确的方法是开设两个班级。 第一个不是线程安全的,而另一个是同步的decorator ,它看起来像这样:

class SyncPosition implements Position {private final Position origin;SyncPosition(Position pos) {this.origin = pos;}@Overridepublic synchronized void increment() {this.origin.increment();}
}

现在,当我们需要position对象是线程安全的时,我们可以使用SyncPosition装饰它:

Position position = new SyncPosition(new SimplePosition()
);

当我们需要一个简单的简单位置而没有任何线程安全性时,我们可以这样做:

Position position = new SimplePosition();

我认为使类功能既丰富线程安全是违反了那个著名的单一责任原则的 。

顺便说一句,这个问题非常接近防御性编程和验证程序之一。

您可能还会发现这些相关的帖子有趣: 您如何使用InterruptedException? ; 为什么InputStream设计错误 ; 限制Java方法执行时间 ; 如何实现一个迭代适配器 ; 通过验证装饰器进行防御性编程 ;

翻译自: https://www.javacodegeeks.com/2017/01/synchronized-decorators-replace-thread-safe-classes.html

线程同步 线程安全

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

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

相关文章

python数学要求_python数学工具之积分(1)

加载库Polygon,绘制积分图形。 fig, ax plt.subplots(figsize(7, 5))表示绘图尺寸为7*5;plt.plot(x, y, b, linewidth2)表示绘制蓝色线宽为2的函数图形;plt.ylim(ymin0)表示y轴最小值为0;Ix np.linspace(a, b)表示lx取值范围为[…

linux swap分区与内存,虚拟内存和swap分区的关系

首先,这两个概念分别对应windows和linux,即:windows:虚拟内存linux:swap分区windows即使物理内存没有用完也会去用到虚拟内存,而Linux不一样 Linux只有当物理内存用完的时候才会去动用虚拟内存(即swap分区)…

.net2.0 orm_Java 8:深入研究速度3.0.1“森林”流ORM

.net2.0 orm沿着这条路 我一直在为开源项目Speedment (它是Stream ORM Java工具包和运行时)做出贡献,并且刚刚发布了一个新的主要版本3.0.1“ Forest”。 版本的发布是以加利福尼亚帕洛阿尔托的大街小巷命名,大多数贡献者都在此工…

JavaScript/JS如何给元素对象添加事件

使用普通的 js 代码给元素对象添加事件 绑定事件,添加事件处理程序: var obj document.getElementById("name"); obj.onclick f1; function f1(){ alert("hello!"); }说明:函数名 f1 就是一个引用数据类型的变量&…

forge开发_使用Forge,WildFly Swarm和Arquillian开发微服务

forge开发在这篇文章中,我们将看到如何使用WildFly Swarm和Forge开发微服务,以及如何使用Arquillian和Rest Assured对其进行测试。 WildFly Swarm提供了一种创新的方法来打包和运行Java EE应用程序,方法是将它们与足够的服务器运行时一起打包…

zynq+linux固化程序,如何在 Zynq UltraScale+ MPSoC 上实现 Linux UIO 设计

原标题:如何在 Zynq UltraScale MPSoC 上实现 Linux UIO 设计简介作者: Alex He (何晔), 赛灵思高级嵌入式应用工程师这里的 UIO 即 Userspace I/O,本文中 UIO 泛指 UIO 设备和 UIO 驱动。它在 Linux kernel 的世界里比较小众&…

python初学者代码示例_Selenium 快速入门笔记和代码示例(Python版)

链接 文档链接: 安装 selenium 模块和 Chrome 浏览器驱动 步骤: 安装 Selenium 模块: pip install selenium 下载浏览器驱动(下载即可,无需安装,使用时要指定它的路径):请参考 https…

用例描述

用例名称:简要说明/描述, 优先级: 参与者: 事件流:就是用例执行时,由一序列活动组成的控制流。 基本事件流:对用例中常规、预期路径的描述。 扩展事件流:主要是对一些异常情况、选…

thinkpad笔记本散热风扇_极致的散热体验,ORICO 全铝DIY双风扇笔记本散热垫评测...

电脑的出现,极大的改变了人类的生活。娱乐、办公、游戏、电子竞技等等都需要用到电脑。而电脑也慢慢的在升级着。电脑的体积也由最开始的的占据几间屋子的庞大体积,到后来的台式机、台式一体机、电脑的体积慢慢的变的越来越小。而便携式笔记本电脑的出现…

清除java_如何在Java地毯下有效地清除问题

清除java因为软件错误可能使我们在开发人员面前看起来很糟糕,并导致其他人对我们的想法减少,所以最好避免编写错误,快速识别和修复错误或掩盖我们的错误。 有许多博客文章和文章讨论如何避免错误以及如何识别和修复错误,因此&…

Web产品的交互说明文档应该怎么写?

经常与开发同学聊天,他们说有一个详细的说明文档可以帮助他们更准确的进行工时评估,还可以帮助他们提高工作效率,减少多余的思考时间。因此在这里分享一些制作交互说明文档的经验。 我先说说说交互原型包含哪些部分? 版本说明及更…

linux类似360软件,linux下有什么类似鲁大师查看电脑配置的软

满意答案drqyna2017.05.26采纳率:40% 等级:11已帮助:5455人linux如何查看系统的硬件配置如何在linux系统下查看系统配置?在图形模式下我们可以很方便的利用Linux的图形工具,点击几下就可以查看到Linux系统的的硬件信…

java 编写代码_如果您在2016年编写过Java代码-这是您不容错过的趋势

java 编写代码2016年最有趣的Java相关主题 关于代码,有很多热门话题,而要跟上所有事情,这是一项全职的工作。 如果您想知道如何从谷壳中分离出小麦,我们已经为您完成了工作。 在下面的文章中,我们将介绍2016年最热门…

thinkphp json_原创干货 | Thinkphp序列化合总

听说转发文章会给你带来好运最近Thinkphp几个版本都出了反序列化利用链,这里集结在一起,下面是复现文章,poc会放在最后01Thinkphp5.1.37环境搭建composercreate-project topthink/think5.1.37 v5.1.37poc演示截图调用链单步调试漏洞起点在\th…

linux安java,Linux安装Java

从人类社会的角度看OO(独家视角)引言 在OO的工作中,我们一定会涉及到类,抽象类和接口.那么类和抽象类以及接口到底扮演的什么角色? 本文主要是从人类社会的角度阐述类与抽象类以及接口的"社会"关系,从而让我们抛弃书 ...include与require的区别&a…

前端和后端的区别

后端工程师负责服务器端应用程序的编写开发(业务逻辑、方法、函数、数据库代码等) 前端工程师负责UI的html代码编写和设计,所以前端工程师一般指网页工程师 前端部分是和用户直接交互的,包括前台和后台部分 客户端其实就是属于前端…

笔记本能安装联想智能云教室吗_挑战Jupyter Notebook:云协作、云硬件,上云的Notebook编程环境...

对全世界的 Python 高手而言,Jupyter Notebook 是目前最流行的编程环境,但它也有一些令人难以忍受的缺点。为此,一个位于旧金山的小团队开发了一款名为 Deepnote 的笔记本工具,这是一种云协作、云硬件,上云的 Notebook…

java自动生成类_自动生成优化的Java类专业知识

java自动生成类如果您今年访问过JavaOne,您可能已经参加了我的演讲“如何从数据库生成定制的Java 8代码”。 在那次演讲中,我展示了如何使用Speedment Open Source工具包使用数据库作为域模型来生成各种Java代码。 我们没有时间要考虑的一件事是&#xf…

在Linux中su和sudo区别,Linux中su和sudo的用法和区别

目录sudosudo:暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码。缺点是每次执行超级用户权限都要在命令前加上 sudo ,优点是在当前终端再使用 sudo 不要再重复输入密码(只对…

neo4j 添加属性_Neo4j:动态添加属性/设置动态属性

neo4j 添加属性我一直在研究一个具有英国国家铁路时刻表的数据集,它们以文本格式为您提供每列火车的出发和到达时间。 例如,可以这样创建代表停止的节点: CREATE (stop:Stop {arrival: "0802", departure: "0803H"})该…