不安全的累加代码,如下

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的实现

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

java并发编程实战《二十一》无锁工具类的更多相关文章

  1. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

  2. 【Java并发编程】2、无锁编程:lock-free原理;CAS;ABA问题

    转自:http://blog.csdn.net/kangroger/article/details/47867269 定义 无锁编程是指在不使用锁的情况下,在多线程环境下实现多变量的同步.即在没有线程 ...

  3. 【JAVA并发编程实战】8、锁顺序死锁

    package cn.study.concurrency.ch10; public class Account { private String staffAccount; //账号 private ...

  4. java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍

    这一节我们来接着介绍JUC集合:CopyOnWriteArraySet和ConcurrentSkipListSet.从名字上来看我们知道CopyOnWriteArraySet与上一节讲到的CopyOn ...

  5. 【JAVA并发编程实战】9、锁分段

    package cn.study.concurrency.ch11; /** * 锁分段 * @author xiaof * */ public class StripedMap { //同步策略:就 ...

  6. Java并发编程阅读笔记-同步容器、工具类整理

  7. java并发编程实战《二》java内存模型

    Java解决可见性和有序性问题:Java内存模型 什么是 Java 内存模型? Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为, Java 内存 ...

  8. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  9. Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...

  10. 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介

    注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...

随机推荐

  1. Django之简易用户系统(3)

    目录 1. 总体设计思路 2. 搭建简易用户系统 2.1 配置模型Model 2. 2 写入数据库: 2.3 数据库验证表: 2.4 路由URL配置: 2.5 用户增加 后台执行脚本配置: 视图模板配 ...

  2. Java_基础(二)

    思想 面向过程的思想: 怎么按步骤把问题解决, 并将步骤编程方法, 一步一步事项, 适合简单不需要协作的任务 面向对象的思想: 怎么设计这个事务 区别与联系 都是解决问题的思维方式, 都是代码组织的方 ...

  3. How to using expression setup BackgroundColor AX2012 SSRS Report[AX2012]

    tile label using [#99ccff] property BackgroundColor - > expression =Iif(Fields!Flag.Value = " ...

  4. python爬虫01在Chrome浏览器抓包

    尽量不要用国产浏览器,很多是有后门的 chrome是首选 百度 按下F12 element标签下对应的HTML代码 点击Network,可以看到很多请求 HTTP请求的方式有好几种,GET,POST, ...

  5. javascript-闭包【面试必备】

    闭包 定义:内层函数可以访问外层函数作用域的变量 意义/用途: 1.封装细节 2.实现模块化 3.常用实战li列表 // querySelectorAll es5支持的一个类似于jq的复杂选择器选取d ...

  6. 【Java】线程的创建方式

    1.继承Thread类方式 这种方式适用于执行特定任务,并且需要获取处理后的数据的场景. 举例:一个用于累加数组内数据的和的线程. public class AdditionThread extend ...

  7. 搭建面向NET Framework的CI/CD持续集成环境(一)Windows服务器安装Jenkins

    前言 网上大多数都是针对主流的Spring Cloud.NET Core的CI/CD方案.但是目前国内绝大部分的公司因为一些历史原因无法简单的把项目从NET Framework切换升级到NET Cor ...

  8. TTL门和MOS门悬空输入的处理

    引言 本来是数字电路学习时很重要的考点,但是总容易忘掉,所以记录一下~ 内容 TTL TTL电路中的TTL是Transistor-Transistor-Logic的英文缩写,指的是晶体管逻辑电路,即T ...

  9. xpth定位元素

  10. Hive 报错Class path contains multiple SLF4J bindings.

    进入hive报错信息如下 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/ ...