总览

原子操作如何在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

向Java添加@atomic操作相关推荐

  1. atomic java_在Java中添加@atomic操作

    atomic java 总览 原子操作如何在Java中工作,OpenJDK / Hotspot中是否存在可以转换为原子的当前替代方法. 反馈 在我以前的文章中, 对可变字段进行原子操作. 有几次指出, ...

  2. Java使用Jdbc操作MySql数据库(一)

    这个示例是Java操作MySql的基本方法. 在这个示例之前,要安装好MySql,并且配置好账户密码,创建一个logininfo数据库,在数据库中创建userinfo数据表.并且在表中添加示例数据. ...

  3. Java数组常见操作

    Java数组常见操作 文章目录 Java数组常见操作 7.0 数组的遍历 1.使用foreach循环访问数组中每个元素. 2.使用简单的for循环(多层循环嵌套)来遍历数组. 7.1 数组长度 7.2 ...

  4. Java原子操作Atomic

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/120854796 本文出自[赵彦军的博客] Java线程安全StampedLock ...

  5. Java剪切板操作大全

    转载自   Java剪切板操作大全 1. 概述 提起剪切板,一般都是在桌面系统或工具中使用.目前,操作Java剪切板有两种形式,这也对应着两种不同的技术Swing和JavaFX. 而剪切板有可以分为系 ...

  6. Java 使用 POI 操作 Excel

    Apache POI 基本介绍 Apache POI 是 Apache 软件基金会提供的 100% 开源库.支持 Excel 库的所有基本功能. 图片来源:易百教程 基本概念 在 POI 中,Work ...

  7. java能打开mob吗_使用 Java添加KeyMob手机聚合平台教程

    下面举个简单的例子来说明如何使用Java 添加广告系列. 1.创建AdWordsUser对象实例. 使用您的身份验证信息和开发人员令牌来创建AdWordsUser实例,这些内容可以存储在属性文件~/a ...

  8. java添加背景图片_Java怎么添加背景图片

    首先,导入相关的包: import java.awt.BorderLayout; import java.awt.Container; import javax.swing.ImageIcon; im ...

  9. java设置界面边框,技术员教你解决Java 添加Word页面边框

    电脑现已成为我们工作.生活和娱乐必不可少的工具了,在使用电脑的过程中,可能会遇到Java 添加Word页面边框的问题,如果我们遇到了Java 添加Word页面边框的情况,该怎么处理怎么才能解决Java ...

最新文章

  1. surface pro 3 linux,新闻|在Surface Pro 3上运行Ubuntu – 虽不完美但很有戏
  2. 人脸检测对齐--Joint Cascade Face Detection and Alignment
  3. sql.xml大于小于号处理的方法
  4. 完整案例:实现延迟队列的两种方法
  5. 用计算机和用纸的区别,英语四级机考与传统纸考的主要区别
  6. 心情随笔(四):重新审视自我
  7. 高铁:繁忙时限制上车补票
  8. 【细胞分割】基于matlab GUI原子力显微镜图像分析【含Matlab源码 1371期】
  9. UVC1.5协议 2
  10. Xen虚拟化环境安装和常用命令
  11. 地产行业主数据建设项目思考
  12. overload方法重载
  13. CF736 D1 格点图,皮克定理
  14. OpenSolaris/Solaris 常见问题解答
  15. opencv实现matlab的median()函数
  16. Drone SETTINGS 页面没有 Trusted
  17. Windows 11系统设置文件夹默认显示方式为“大图标”的方法
  18. 1]解决java.util.concurrent.RejectedExecutionException
  19. WPF 3D模型介绍及使用
  20. 20级网络学生---循环

热门文章

  1. 2016蓝桥杯省赛---java---B---7(剪邮票)
  2. Java获取指定月份的最后一天
  3. 联想linux笔记本评测,联想(lenovo)G460AL-ITH Linux笔记本电脑CPU测试评测-ZOL中关村在线...
  4. windows为什么把linux打败了,快二十年了,人们为什么还是没有抛弃 Windows 转向 Linux?...
  5. 优先队列——二项队列(binominal queue)
  6. php cdi_Quarkus的其他(非标准)CDI功能
  7. skynet.fork_Apache Ant 1.10.6发布–用于junitlauncher的fork模式以及新的jmod和链接任务
  8. javax线程池超时结束_没有Javax的Jakarta EE:这次世界也不会结束
  9. pbfunc外部扩展函数_从外部CorDapp扩展和覆盖流
  10. mybatis缓存二级缓存_MyBatis缓存与Apache Ignite的陷阱