Java多线程系列——原子类的实现(CAS算法)
来源:互联网 发布:南京云宝网络怎么样 编辑:程序博客网 时间:2024/05/24 06:05
Java提供的原子类是靠 sun 基于 CAS 实现的,CAS 是一种乐观锁。关于乐观锁与悲观锁。
原子变量类相当于一种泛化的 volatile 变量,能够支持原子的和有条件的读-改-写操作。AtomicInteger 表示一个int类型的值,并提供了 get 和 set 方法,这些 Volatile 类型的int变量在读取和写入上有着相同的内存语义。它还提供了一个原子的 compareAndSet 方法(如果该方法成功执行,那么将实现与读取/写入一个 volatile 变量相同的内存效果),以及原子的添加、递增和递减等方法。AtomicInteger 表面上非常像一个扩展的 Counter 类,但在发生竞争的情况下能提供更高的可伸缩性,因为它直接利用了硬件对并发的支持。
AtomicInteger的实现
AtomicInteger 是一个支持原子操作的 Integer 类,就是保证对 AtomicInteger 类型变量的增加和减少操作是原子性的,不会出现多个线程下的数据不一致问题。如果不使用 AtomicInteger,要实现一个按顺序获取的 ID,就必须在每次获取时进行加锁操作,以避免出现并发时获取到同样的 ID 的现象。
接下来通过源代码来看 AtomicInteger 具体是如何实现的原子操作。
首先看 value 的声明:
private volatile int value;
volatile 修饰的 value 变量,保证了变量的可见性。
incrementAndGet() 方法,下面是具体的代码:
public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
通过源码,可以知道,这个方法的做法为先获取到当前的 value 属性值,然后将 value 加 1,赋值给一个局部的 next 变量,然而,这两步都是非线程安全的,但是内部有一个死循环,不断去做 compareAndSet 操作,直到成功为止,也就是修改的根本在 compareAndSet 方法里面,compareAndSet()方法的代码如下:
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}
compareAndSet()方法调用的compareAndSwapInt()方法的声明如下,是一个native方法。
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, intvar5);
compareAndSet 传入的为执行方法时获取到的 value 属性值,next 为加 1 后的值, compareAndSet 所做的为调用 Sun 的 UnSafe 的 compareAndSwapInt 方法来完成,此方法为 native 方法,compareAndSwapInt 基于的是 CPU 的 CAS 指令来实现的。所以基于 CAS 的操作可认为是无阻塞的,一个线程的失败或挂起不会引起其它线程也失败或挂起。并且由于 CAS 操作是 CPU 原语,所以性能比较好。
类似的,还有 decrementAndGet() 方法。它和 incrementAndGet() 的区别是将 value 减 1,赋值给next 变量。
AtomicInteger 中还有 getAndIncrement() 和 getAndDecrement() 方法,他们的实现原理和上面的两个方法完全相同,区别是返回值不同,前两个方法返回的是改变之后的值,即 next。而这两个方法返回的是改变之前的值,即 current。还有很多的其他方法,就不列举了。
CAS算法
CAS(Compare-And-Swap)算法保证数据操作的原子性。
CAS 算法是硬件对于并发操作共享数据的支持。
CAS 包含了三个操作数:
内存值 V
预估值 A
更新值 B
当且仅当 V == A 时,V 将被赋值为 B,否则循环着不断进行判断 V 与 A 是否相等。
- Java多线程系列——原子类的实现(CAS算法)
- Java多线程系列(四)—CAS操作和Automic原子类
- “J.U.C”:原子类的实现(CAS算法)
- JAVA CAS 原子类及多线程总结
- Java并发编程系列(四)----CAS与原子类
- java中的CAS和原子类的实现
- Java多线程系列--【JUC原子类01】- AtomicLong原子类
- Java多线程系列--【JUC原子类02】- AtomicLongArray原子类
- Java多线程系列--【JUC原子类03】- AtomicReference原子类
- Java多线程系列--【JUC原子类04】- AtomicLongFieldUpdater原子类
- Java多线程系列--“JUC原子类”
- java原子类和CAS
- 【Java】CAS机制 原子类
- java多线程--原子类
- java 多线程 原子类
- 【Java多线程】原子类
- Java多线程系列--“JUC原子类”02之 AtomicLong原子类
- Java多线程系列--“JUC原子类”03之 AtomicLongArray原子类
- UnityAI行为-----群组行为之群集动画
- 到了Vue2.x有哪些变化?—— 组件通信
- 一键搭建本地yum源
- iframe中使用My97DatePicker WdatePicker()无法弹框
- Leetcode: symmetric-tree
- Java多线程系列——原子类的实现(CAS算法)
- [Leetcode] 155. Min Stack 解题报告
- foreach后通过checkbox获取值
- ${pageContext.request.contextPath} JSP取得绝对路径
- Vue2版Cnode社区webapp
- 那些年我们遇到的坑(2)-FeignClient
- 题目1064:反序数
- Vue2.0进阶组件篇4 突如其来(时间倒计时组件)
- Kotlin语法(六)