向Java添加@atomic操作

总览

原子操作如何在Java中工作,OpenJDK / Hotspot中是否存在可以转换为原子的当前替代方法。

反馈

在我以前的文章中, 对可变字段进行原子操作。 有人指出,无论好意如何,“修复”先前的行为都不太可能继续进行。


替代方法是添加@atomic注释。 这样做的好处是仅适用于新代码,而不会冒险破坏旧代码。

注意:故意使用小写字母,因为它*不*遵循当前的编码约定。

原子操作

任何带有@atomic列出的字段都将使整个表达式具有原子性。 非易失性和非原子性变量可以在开始时读取,或者在表达式完成后进行设置。 该表达式本身可能需要在某些平台,CAS操作或TSX上锁定,具体取决于CPU技术。

如果仅读取字段,或者也只写入一个字段,则该字段与volatile相同。

原子布尔

当前,AtomicBoolean使用4个字节,外加一个对象标头,并带有可能的填充(以及引用)。如果该字段是内联的,则可能看起来像这样

@atomic boolean flag;
// toggle the flag.
this.flag = !this.flag;

但是如何运作? 并非所有平台都支持1字节原子操作,例如Unsafe确实具有1字节CAS操作。 这可以通过掩膜来完成。

// possible replacement.
while(true) {int num = Unsafe.getUnsafe().getVolatileInt(this, FLAG_OFFSET & ~3); // word align the access.int value ^= 1 << ~(0xFF << (FLAG_OFFSET & 3) * 8) ;if (Unsafe.getUnsafe().compareAndSwapInt(this, FLAG_OFFSET & ~3, num, value))break;
}

原子双

不支持的类型是AtomicDouble,但这是AtomicLong的变体。 考虑这个例子。

@atomic double a = 1;
volatile double b = 2;a += b;

今天如何实施?

while(true) {double _b = Unsafe.getUnsafe().getVolatileDouble(this, B_OFFSET);double _a = Unsafe.getUnsafe().getVolatileDouble(this, A_OFFSET);long aAsLong = Double.doubleToRawLongBits(_a);double _sum = _a + _b;long sumAsLong = Double.doubleToRawLongBits(_a);if (Unsafe.getUnsafe().compareAndSwapLong(this, A_OFFSET, aAsLong, sumAsLong))break;
}

两个原子场

使用Intel TSX,您可以将硬件事务包装在多个字段中,但是如果没有TSX,该事务是否仍可以完成而无需求助于锁。

@atomic int a = 1, b = 2;a += b * (b % 2 == 0 ? 2 : 1);

如果字段在一起,仍然可以使用CAS来完成。 计划执行CAS2操作以检查两个64位值。 现在,此示例将使用两个4字节值。

assert A_OFFSET + 4 == B_OFFSET;
while(true) {long _ab = Unsafe.getUnsafe().getVolatileLong(this, A_OFFSET);int _a = getLowerInt(_ab);int _b = getHigherInt(_ab);int _sum = _a + _b * (_b % 2 == 0 ? 2 : 1);int _sum_ab = setLowerIntFor(_ab, _sum);if (Unsafe.getUnsafe().compareAndSwapLong(this, A_OFFSET, _ab, _sum_ab))break;
}

注意:此操作可以原子方式处理a或b或两者的更改。

原子参考

对不可变对象(例如BigDecimal)的常见用例操作。

@atomic BigDecimal a;
BigDecimal b;a = a.add(b);

可以在具有CompressedOops或32位JVM的系统上以这种方式实现。

BigDecimal _b = this.b;
while(true) {BigDecimal _a = (BigDecimal) Unsafe.getUnsafe().getVolatileObject(this, A_OFFSET);BigDecimal _sum = _a.add(_b);if (Unsafe.getUnsafe().compareAndSwapLong(this, A_OFFSET, _a, _sum))break;
}

更复杂的例子

对于您的平台,总会有一些例子过于复杂。 在带有TSX或HotSpot支持的系统的系统上,它们可能很好,但是您需要回退。

@atomic long a, b, c, d;a = (b = (c = d + 4) +  5 ) + 6;

当前不支持此功能,因为它在一个表达式中设置了多个long值。 但是,回退可能是使用现有的锁。

synchronized(this) {a = (b = (c = d + 4) +  5 ) + 6;
}

结论

通过添加注释,我们可以在常规字段中添加原子操作,而无需更改语法。 这将是对语言的自然扩展,而不会破坏向后的可比性。

翻译自: https://www.javacodegeeks.com/2014/07/adding-atomic-operations-to-java.html

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

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

相关文章

JSP页面中使用超链接进行传输参数(参数是一个本地磁盘链接)问题

在使用COS组件进行文件上传下载时遇到一个下载问题 刚开始我存的地址格式为&#xff1a;D:\tool\upload发现一直报Error parsing HTTP request header Note: further occurrences of HTTP header p的错误 后来发现使用超链接传参数不支持“\”字符&#xff0c;可能是转义字符…

pt-online-schema-change VS oak-online-alter-table【转】

前言 在上篇文章中提到了MySQL 5.6 Online DDL&#xff0c;如果是MySQL 5.5的版本在DDL方面是要付出代价的&#xff0c;虽然已经有了Fast index Creation&#xff0c;但是在添加字段还是会锁表的&#xff0c;而且在添加删除辅助索引是会加S锁&#xff0c;也就是无法进行写操作。…

The Pilots Brothers' refrigerator

#include<iostream> #include<cstdio> #include<string> using namespace std; int mem[4][4];//用于储存翻转次数&#xff0c;如果是偶数&#xff0c;则相当于没有翻转int main(){char ch;for (int x 0; x<4; x){//按sample的顺序,x代表纵行,y是横列for…

Jax-RS自定义异常处理

使用JEE的好处之一是可用的组件确实是非常标准的。 在使用JAX-RS时&#xff0c;有时您需要控制如何处理异常并将其反馈给用户。 默认情况下&#xff0c;如果引发异常&#xff0c;您将得到一些可怕的HTTP 500内部服务器异常&#xff0c;从而暴露Web服务的内部故障。 考虑以下要…

开张大吉!

新工作&#xff0c;新技术&#xff0c;新开始&#xff01; 开这个博客&#xff0c;希望能记录自己在新公司的点点滴滴&#xff01; 转载于:https://www.cnblogs.com/newman78/archive/2008/05/14/1197227.html

html中评论应该怎么写,HTML-评论

HTML-评论注释是一段代码&#xff0c;任何网络浏览器都将忽略它。最好在HTML代码中添加注释&#xff0c;尤其是在复杂的文档中&#xff0c;以指示文档的各个部分&#xff0c;以及任何其他注释代码的人。注释可帮助您和其他人理解您的代码并提高代码的可读性。HTML注释位于标记之…

vue命令行错误处理

全局安装vue/cli时&#xff1a;npm install -g vue/cli &#xff08;1&#xff09;Error: EACCES: permission denied, access /usr/local/lib/node_modules/vue/cli 原因: 执行命令时没有获得管理员权限 解决办法: 在命令前面加上sudo即可.然后输入电脑的管理员密码操作即可…

RAC(ReactiveCocoa)介绍(一)

最近在学习RAC&#xff0c;之前在iOS工作中&#xff0c;类之间的传值&#xff0c;无非是block、delegate代理、KVO和Notification等这几种方法。在RAC中&#xff0c;同样具备替代block、delegate代理、KVO和Notification&#xff0c;UI target、定时器timer、数据结构等各种方式…

祖国啊

祖国啊&#xff0c;我们用鲜血供奉您...转载于:https://www.cnblogs.com/westsource/archive/2008/05/22/1204827.html

一段简单的html 5 音频,5个用于处理HTML5音频的库和API

在过去的几个月中&#xff0c;我遇到了许多不同的库&#xff0c;它们利用了相对较新的HTML5 Audio API以及更著名的HTML5 Audio Element及其更简单的API。我以为我会在本文中分享这些库中的一小部分&#xff0c;以向您展示如果选择创建需要操纵声音文件的游戏或应用程序&#x…

下载软件的好地方

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/转载于:https://www.cnblogs.com/pengzhi12345/p/11197510.html

用于JMX访问的Apache Ant任务

我想从Ant任务中调用JMX操作。 但是&#xff0c;找到可用的蚂蚁任务库及其用法非常棘手。 因此&#xff0c;让我分享我的经验&#xff0c;使他人更轻松。 JMX操作的Ant任务 我决定遵循Tomcat文档并使用与tomcat一起分发的ant任务。 仅作记录用途&#xff0c;并不限于Tomcat部…

async 和 await 之异步编程的学习

async修改一个方法&#xff0c;表示其为异步方法。而await表示等待一个异步任务的执行。js方面&#xff0c;在es7中开始得以支持&#xff1b;而.net在c#5.0开始支持。本文章将分别简单介绍他们在js和.net中的基本用法。 一、在js中的实现 js中的异步&#xff0c;还是基于Prom…

WinAPI: SetRect 及初始化矩形的几种办法

本例分别用五种办法初始化了同样的一个矩形, 运行效果图:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 class(TForm)Button1: TButton;Button2: TButton;Button3: TButton;Button4: TBu…

Eureka 集群高可用配置.

SERVER:1 server:port: 1111 eureka:instance:hostname: ${spring.cloud.client.ip-address}instance-id: ${eureka.instance.hostname}:${server.port}preferIpAddress: true #指定通过IP注册,一般服务集群时配置,需要ip-address参数一起设置(保证hostName和ip-address一…

备忘录——通过RVA计算文件位置

备忘录——通过RVA计算文件位置 原创&#xff1a;Anders Liu 摘要&#xff1a;本文介绍了如何通过PE文件中某一项的RVA来计算其在文件中的位置。 参考文献 ECMA-335——Common Language Infrastructure (CLI) 4th Edition, June 2006 范畴 该备忘录描述了在分析PE&#xff08;可…

使用Java 8的Builder模式

我在一个环境中工作&#xff0c;其中通过调用远程服务而不是使用数据库来执行大量日常脚本任务。 对于许多脚本编写任务&#xff0c;我经常使用Groovy&#xff0c;而Groovy专门用于该任务的最有用的功能之一就是它是用流畅的Builders构建的 。 现在&#xff0c;Groovy构建器利…

Asp.net2.0工具包AjaxControlToolkit下载和安装

Asp.net2.0工具包AjaxControlToolkit下载和安装:点击下载 环境设置如下&#xff1a;A!a.S-DQ0ITPUB个人空间P,JN2y2b o5K 下载完 ASPAJAXExtSetup.msi 安装更新后在你的系统盘下的&#xff08;以C盘为例&#xff09; 出现这个 文件夹&#xff1a;ITPUB个人空间nA*O2U/l8i69s#o0…

中后端管理系统前后分离、前端框架的实现拙见

一、实现思路 在实践中后台管理系统的前后端分离时&#xff0c;往往会因为业务量的增加使其前端项目难以维护&#xff0c;以及打包时间不理想&#xff0c;还有业务系统与框架之间区分不在明显。本文是本人从另一个角度提出的一种解决方案&#xff0c;希望各位提出宝贵的建议。…

初见mobX

先看如下的代码 const {observable} mobox; const {observer}mobxReact; const {Component}React; const appStateobservable({count:0 }) appState.incrementfunction(){this.count } appState.decrementfunction(){this.count-- } observer class Counter extends Component{…