对于简单的原子性问题,还有一种无锁方案,先看看如何利用原子类解决累加器问题。

public class Test {AtomicLong count = new AtomicLong(0);public void add10K() {int idx = 0;while(idx++ < 10000) {count.getAndIncrement();}}}

无锁方案相对互斥锁方案,最大的好处就是性能。

无锁方案的实现原理

其实原子类性能高的秘密很简单,硬件支持而已。CPU 为了解决并发问题,提供了 CAS 指令(CAS,全称是 Compare And Swap,即“比较并交换”)。CAS 指令包含 3 个参数:共享变量的内存地址 A、用于比较的值 B 和共享变量的新值 C;并且只有当内存中地址 A 处的值等于 B 时,才能将内存中地址 A 处的值更新为新值 C。作为一条 CPU 指令,CAS 指令本身是能够保证原子性的。

你可以通过下面 CAS 指令的模拟代码来理解 CAS 的工作原理。在下面的模拟程序中有两个参数,一个是期望值 expect,另一个是需要写入的新值 newValue,只有当目前 count的值和期望值 expect 相等时,才会将 count 更新为 newValue

class SimulatedCAS{int count;public synchronized int cas(int expect, int newValue){// 读目前 count 的值int curValue = count;// 比较目前 count 值是否 == 期望值if(curValue == expect){// 如果是,则更新 count 的值count = newValue;}// 返回写入前的值return curValue;}}

使用 CAS 来解决并发问题,一般都会伴随着自旋,而所谓自旋,其实就是循环尝试。

class SimulatedCAS{volatile int count;// 实现 count+=1public void addOne(){do {newValue = count+1; //①}while(count != cas(count,newValue) //②}// 模拟实现 CAS,仅用来帮助理解public synchronized int cas(int expect, int newValue){// 读目前 count 的值int curValue = count;// 比较目前 count 值是否 == 期望值if(curValue == expect){// 如果是,则更新 count 的值count= newValue;}// 返回写入前的值return curValue;}
}

但是在 CAS 方案中,有一个问题可能会常被你忽略,那就是ABA的问题。什么是 ABA 问题呢?

假设 count 原本是 A,线程 T1 在执行完代码①处之后,执行代码②处之前,有可能 count 被线程 T2 更新成了 B,之后又被 T3 更新回了 A,这样线程T1 虽然看到的一直是 A,但是其实已经被其他线程更新过了,这就是 ABA 问题。

Java 如何实现原子化的 count += 1

在 Java 1.8 版本中,getAndIncrement() 方法会转调 unsafe.getAndAddLong() 方法。这里 this 和 valueOffset 两个参数可以唯一确定共享变量的内存地址。

final long getAndIncrement() {return unsafe.getAndAddLong(this, valueOffset, 1L);
}

unsafe.getAndAddLong() 方法的源码如下

public final long getAndAddLong(Object o, long offset, long delta){long v;do {// 读取内存中的值v = getLongVolatile(o, offset);} while (!compareAndSwapLong(o, offset, v, v + delta));return v;
}// 原子性地将变量更新为 x
// 条件是内存中的值等于 expected
// 更新成功则返回 true
native boolean compareAndSwapLong(Object o, long offset, long expected,long x);

原子类概览

1. 原子化的基本数据类型

getAndIncrement() // 原子化 i++
getAndDecrement() // 原子化的 i--
incrementAndGet() // 原子化的 ++i
decrementAndGet() // 原子化的 --i
// 当前值 +=delta,返回 += 前的值
getAndAdd(delta)
// 当前值 +=delta,返回 += 后的值
addAndGet(delta)
//CAS 操作,返回是否成功
compareAndSet(expect, update)
// 以下四个方法
// 新值可以通过传入 func 函数来计算
getAndUpdate(func)
updateAndGet(func)
getAndAccumulate(x,func)
accumulateAndGet(x,func)

Java并发编程实战~原子类相关推荐

  1. Java并发编程—Atomic原子类

    目录 Atomic 1. AtomicInteger a. 多线程并发访问问题 b. 用 AtomicInteger 类解决 2. AtomicIntegerArray a. 多线程并发访问问题 b. ...

  2. 视频教程-Java并发编程实战-Java

    Java并发编程实战 2018年以超过十倍的年业绩增长速度,从中高端IT技术在线教育行业中脱颖而出,成为在线教育领域一匹令人瞩目的黑马.咕泡学院以教学培养.职业规划为核心,旨在帮助学员提升技术技能,加 ...

  3. 【极客时间】《Java并发编程实战》学习笔记

    目录: 开篇词 | 你为什么需要学习并发编程? 内容来源:开篇词 | 你为什么需要学习并发编程?-极客时间 例如,Java 里 synchronized.wait()/notify() 相关的知识很琐 ...

  4. Java并发编程实战之互斥锁

    文章目录 Java并发编程实战之互斥锁 如何解决原子性问题? 锁模型 Java synchronized 关键字 Java synchronized 关键字 只能解决原子性问题? 如何正确使用Java ...

  5. JAVA并发编程实战——共享对象

    目录 思维导图 1. 可见性 1. 1 过期数据 1.2 锁和可见性 1.3 Volatile变量 2. 发布和逸出 2.1 安全构建实践 3. 线程封闭 3.1 栈限制 3.2 ThreadLoca ...

  6. 《Java 并发编程实战》--读书笔记

    Java 并发编程实战 注: 极客时间<Java 并发编程实战>–读书笔记 GitHub:https://github.com/ByrsH/Reading-notes/blob/maste ...

  7. Java并发编程实战————Executor框架与任务执行

    引言 本篇博客介绍通过"执行任务"的机制来设计应用程序时需要掌握的一些知识.所有的内容均提炼自<Java并发编程实战>中第六章的内容. 大多数并发应用程序都是围绕&qu ...

  8. Java并发编程实战笔记2:对象的组合

    设计线程安全的类 在设计现车让安全类的过程之中,需要包含以下三步: 找出构成对象状态的所有变量 找出约束状态变量的不变性条件 建立对象状态的并发访问策略 实例封闭 通过封闭机制与合适的加锁策略结合起来 ...

  9. aqs clh java_【Java并发编程实战】—– AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...

最新文章

  1. 多重采样和超级采样哪个流畅_OpenGL多重采样:结果与未使用多重采样时的结果相同...
  2. OpenSuse Linux 的单用户模式
  3. Dubbo 源码分析 - SPI 机制
  4. asp.net面试的题目
  5. 大华管理平台用户名_智能财务引领商业与管理变革——浙大EMBA首席财务官研习社走进大华股份...
  6. 一个简单的Eclipse调试Debug流程(四)
  7. 用遗传算法求3维函数 的最小值_遗传算法可视化项目(4):遗传算法
  8. 关于C语言数据类型的PPT,C语言基本的数据类型.ppt
  9. paip.程序不报错自动退出的解决
  10. 逻辑回归案例模板——信用卡欺诈检测
  11. C语言全局变量,局部变量,静态局部变量的区分
  12. SpringBoot+tomcat发布之war包发布
  13. 游戏制作之路(3)Blender制作极简动画
  14. android 后台监听按键,Android监听home键的方法详解
  15. Centos7中MySQL的安装并设置开机启动
  16. Magento常用插件整理收集
  17. 架构设计-架构愿景分析
  18. 在Mac系统中将html网页转成PDF格式
  19. 2021年各省高考日语成绩查询,2021年各省高考满分是多少
  20. 指纹识别综述(10): 深度学习方法

热门文章

  1. 论文浅尝 - CIKM2021 | DT-GCN: 一种双曲空间中的数据类型感知的知识图谱表示学习模型...
  2. 领域应用 | 完备的娱乐行业知识图谱库如何建成?爱奇艺知识图谱落地实践
  3. 参会邀请 - CCKS2020 | 2020全国知识图谱与语义计算大会(CCKS2020)明日开幕
  4. 文本相似度-相似度度量
  5. Android官方开发文档Training系列课程中文版:支持不同的设备之支持不同的屏幕
  6. 笔记:《幸福的方法》
  7. python enumerate用法总结(转)
  8. Restful Service 中 DateTime 在 url 中传递
  9. 有关 Lambda linq练习 有待整理
  10. Mac下关闭Sublime Text 3的更新检查