java并发编程实战《二十一》无锁工具类
不安全的累加代码,如下
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并发编程实战《二十一》无锁工具类的更多相关文章
- Java并发编程实战.笔记十一(非阻塞同步机制)
关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...
- 【Java并发编程】2、无锁编程:lock-free原理;CAS;ABA问题
转自:http://blog.csdn.net/kangroger/article/details/47867269 定义 无锁编程是指在不使用锁的情况下,在多线程环境下实现多变量的同步.即在没有线程 ...
- 【JAVA并发编程实战】8、锁顺序死锁
package cn.study.concurrency.ch10; public class Account { private String staffAccount; //账号 private ...
- java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍
这一节我们来接着介绍JUC集合:CopyOnWriteArraySet和ConcurrentSkipListSet.从名字上来看我们知道CopyOnWriteArraySet与上一节讲到的CopyOn ...
- 【JAVA并发编程实战】9、锁分段
package cn.study.concurrency.ch11; /** * 锁分段 * @author xiaof * */ public class StripedMap { //同步策略:就 ...
- Java并发编程阅读笔记-同步容器、工具类整理
- java并发编程实战《二》java内存模型
Java解决可见性和有序性问题:Java内存模型 什么是 Java 内存模型? Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为, Java 内存 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- Java并发编程实战 03互斥锁 解决原子性问题
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介
注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...
随机推荐
- AC86U kx上网
AC86U收到很久了,为了能够kx上网免不了一番折腾. 准备 U盘一个, 读写速度要大于30M/s, 用于制作虚拟内存 步骤大致如下: 1.下载koolshare固件 我这里下载的是官改固件:http ...
- 教你如何 分析 Android ANR 问题
ANR介绍 ANR 的全称是 Application No Responding,即应用程序无响应,具体是一些特定的 Message (Key Dispatch.Broadcast.Service) ...
- 【KataDaily 191015】Sort the Gift Code
题目: Happy Holidays fellow Code Warriors! Santa's senior gift organizer Elf developed a way to repres ...
- 手把手教你使用容器服务 TKE 集群审计排查问题
概述 有时候,集群资源莫名被删除或修改,有可能是人为误操作,也有可能是某个应用的 bug 或恶意程序调用 apiserver 接口导致,需要找出 "真凶".这时候,我们需要为集群开 ...
- C++ 基础 1:C++ 对 C 语言的增强
1 namespace 命名空间 1.1 C++ 命名空间的定义 C++标准 引入了关键字 namespace(命名空间),可以更好地控制标识符的作用域. namespace name { ... } ...
- WSL-Ubuntu18.04 磁盘迁移 与 ns3-gym 安装
WSL 安装 win10 版本应大于或等于 1903 win10 设置页面 输入 控制面板 并点击进入 找到 程序和功能 并打开 找到 启动或关闭 Windows 功能 并打开 向下拉 勾选 适用于L ...
- Javascript的运行效率是原生代码的20%-30%
所以jser们,写代码更仔细些吧. http://www.cnblogs.com/codemood/p/3213459.html
- CSS两列布局的多种方式
两列布局(一侧固定宽度,一侧自适应),在工作中应该是经常使用到,可以说是前端基础了.这种两列布局的样式是我们在平时工作中非常常见的设计,同时也是面试中要求实现的高频题.很有必要掌握以备不时之需.这里总 ...
- 为什么人们总是认为epoll 效率比select高!!!!!!
今天看公司代码时,发现代码里面使用的事清一色的代码使用epoll, 所以就得说一说了:宏观看一看epoll 和select的实现: select原理概述 调用select时,会发生以下事情: 从用户空 ...
- 基于 Nebula Operator 的 K8s 自动化部署运维
摘要:Nebula Operator 是 Nebula Graph 在 Kubernetes 系统上的自动化部署运维插件.在本文,你将了解到 Nebula Operator 的特性及它的工作原理. 从 ...