atomic java

总览

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

atomic java

atomic java_在Java中添加@atomic操作相关推荐

  1. java中的Atomic类

    文章目录 问题背景 Lock 使用Atomic java中的Atomic类 问题背景 在多线程环境中,我们最常遇到的问题就是变量的值进行同步.因为变量需要在多线程中进行共享,所以我们必须需要采用一定的 ...

  2. Java 中添加背景音乐

    Java 中添加背景音乐 GUI 中添加背景音乐 添加循环播放的背景音乐 背景音乐音量调节 好了,以上主要是多放几个 关键词,方便能让需要的人都能搜到 以下就是可直接使用的方法, 之后按提示导包就 o ...

  3. java创建的窗口无法关闭_在Java中添加canvas后无法关闭窗口(Can't close window after adding canvas in Java)...

    在Java中添加canvas后无法关闭窗口(Can't close window after adding canvas in Java) public class Screen extends Ca ...

  4. java中的IO操作总结

    java中的IO操作 在java中IO涉及的范围比较大,本文主要针对文件内容的读写 对于文件内容的操作主要分为两大类: 字符流:有两个抽象类 writer Reader 其对应子类FileWriter ...

  5. java soap 头_如何在Java中添加Soap标头

    我有一个来自oracle的NO.net Web服务,要访问,我需要添加soap标头.如何在Java中添加soap标头? Authenticator.setDefault(new ProxyAuthen ...

  6. java中使用lua操作redis

    java中使用lua脚本参见我的上一篇文章 lua基础 本篇简单说下java中使用lua操作redis的示例,如下: 先引入jedis <dependency><groupId> ...

  7. java中四种操作(DOM、SAX、JDOM、DOM4J)xml方式详解与比较(转)

    java中四种操作(DOM.SAX.JDOM.DOM4J)xml方式详解与比较(转) http://wishlife.javaeye.com/blog/181865 posted on 2010-12 ...

  8. 深圳软件测试培训:java中数组的操作

    深圳软件测试培训:java中数组的操作 一.数组最常见的一个操作就是遍历. 因为数组的每个元素都可以通过索引来访问,通过for循环就可以遍历数组. public class M { public st ...

  9. Java进阶——Java中的Atomic原子特性

    引言 这篇文章会从基本概念中入手,首先,从volatile关键字引出原子性的概念和Atomic包,然后,介绍Atomic在使用中的用到的CAS技术和遇到的ABA问题,最后,介绍Atomic的成员和例子 ...

最新文章

  1. Linux关闭开关机动画,centos7删除开机动画及修改启动菜单
  2. Linux下百度云盘报 获取bdstoken失败
  3. 在webpack中使用eslint配置(详细教程)-js教程-PHP中文网
  4. E:K-periodic Garland(DP)
  5. 三张表有重复字段_什么?搞不定Kafka重复消费?
  6. cookie中转注入
  7. springmvc + ibatis 框架的搭建
  8. 为什么静态方法中不可以直接访问非静态方法?
  9. 用单片机c语言输入8位输出,单片机C语言教程(二)
  10. 汽车驾驶 - 侧方停车
  11. oracle访问syno,[Oracle]同义词(synonym)
  12. layui 弹出层 点击遮罩层关闭
  13. 【Python百日进阶-Web开发-Feffery】Day437 - fac实例:使用fac中上传组件时实现自主控制uploadId
  14. 【渝粤教育】21秋期末考试建筑设备10327k1
  15. Et aliquam sunt quasi harum unde.Deserunt impediSofort wohnen früh aus t quidem vel dolorum ducimus.
  16. iOS 11种键盘布局总结
  17. 【AAAI 2021】跨层知识蒸馏:Cross-Layer Distillation with Semantic Calibration
  18. 关于XMLHttpRequest的xhr.readyState和 xhr.status 的简单使用
  19. 数组的趣味应用-鲁智深吃馒头
  20. Android 12.0 屏蔽FallbackHome机制去掉android正在启动直接进入默认Launcher功能实现

热门文章

  1. 欢乐纪中某B组赛【2019.1.29】
  2. jzoj1161-机器人M号【欧拉函数,dp】
  3. 【dfs】【hash】有趣的英语角(2015特长生 T2/luogu 1019)
  4. 【递归】桐桐的递归函数
  5. Educational Codeforces Round 48
  6. Redis 常用操作命令,非常详细
  7. Java 多线程 —— 深入理解 volatile 的原理以及应用
  8. Spring思维导图,让Spring不再难懂(cache篇)
  9. HTML中常用知识点整理
  10. JS中对象创建的五中方式