不安全的累加代码,如下

1 public class Test {
2 long count = 0;
3 void add10K() {
4 int idx = 0;
5 while(idx++ < 10000) {
6 count += 1;
7 }
8 }
9 }

  不安全的原因是count的可见性以及count += 1的原子性

使用AtomicLong

 1 public class Test {
2 AtomicLong count =
3 new AtomicLong(0);
4 void add10K() {
5 int idx = 0;
6 while(idx++ < 10000) {
7 count.getAndIncrement();
8 }
9 }
10 }

好处:

 性能提升

原理:

 硬件支持。CPU 为了解决并发问题,提供了 CAS 指令(CAS,全称是 Compare And Swap,即“比较并交换”)。

  CAS 指令包含 3 个参数:共享变量的内存地址 A、用于比较的值 B 和共享变量的新值 C并且只有当内存中地址 A 处的值等于 B 时,才能将内存中地址 A 处的值更新为新值 C。作为一条 CPU 指令,CAS 指令本身是能够保证原子性的。

源码:

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

  思考:这里为什么要传this?来看一下AtomicLong这个类的结构

  重点看成员变量,getAndAddLong传this和offset肯定是为了获取这个value值,但是为什么不直接传value?实际上这就是引用传值和非引用传值,value是成员变量,从共享内存读,如果直接非引用传值,那在value传入后加入内存屏障之前共享内存中value的值被修改了怎么办?

源码:

 1 public final long getAndAddLong(
2 Object o, long offset, long delta){
3 long v;
4 do {
5 // 读取内存中的值
6 v = getLongVolatile(o, offset);
7 } while (!compareAndSwapLong(
8 o, offset, v, v + delta));
9 return v;
10 }
11 //原子性地将变量更新为x
12 //条件是内存中的值等于expected
13 //更新成功则返回true
14 native boolean compareAndSwapLong(
15 Object o, long offset,
16 long expected,
17 long x);

总结:

  原子类针对单个共享变量,多个共享变量使用互斥锁

以上,还没说完,

  另外还有CAS的ABA问题

等等搞一下openjdk的源码编译,看看compareAndSwapLong的实现

  太特么打击人了,想编译成功太耗费时间,先抛了。

最新文章

  1. 深入理解CSS盒子模型
  2. js正则表达式图形化工具-rline
  3. ZC706以太网扩展板接口
  4. (十) 一起学 Unix 环境高级编程 (APUE) 之 线程控制
  5. Json(2)-DataContractJsonSerializer
  6. EIGamal密码体制
  7. MongoDB的安装和基本操作
  8. 关于安装linux时要怎么分区的考虑的參考方式?
  9. MySQL数据库安装(CentOS操作系统/tar.gz方式)
  10. 微信小程序 服务器端生成用户登陆环节的 3rd_session
  11. 【20171027中】alert(1) to win 第13,14,15,16题
  12. Wannafly挑战赛3 record
  13. pd.read_csv() 、to_csv() 之 常用参数
  14. Hibernate若干知识点
  15. Python中多个列表与字典的合并方法
  16. 【Android】让Python在Android系统上飞一会儿
  17. Java面试(一) -- 基础部分(1)
  18. 【转载】COM 组件设计与应用(六)——用 ATL 写第一个组件
  19. 铁轨(rails, ACM/ICPC CERC 1997,Uva 514)
  20. Asp.net MVC Comet 推送

热门文章

  1. 浅谈OpenGL之DSA
  2. 【Kata Daily 190916】String end with?(字母结尾)
  3. leetcode76set-matrix-zeroes
  4. HTML5 实现的一个俄罗斯方块实例代码
  5. flex-shrink值的计算
  6. 虚拟DOM与diff算法
  7. java 打包压缩包下载文件
  8. Mysql binlog备份数据及恢复数据,学会这个,我在也不怕删库跑路啦~
  9. 深度分析:Java中如何如理异常,一篇帮你搞定!
  10. Camtasia的标记使用方法