博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程系列——原子类的实现(CAS算法)
阅读量:5244 次
发布时间:2019-06-14

本文共 2027 字,大约阅读时间需要 6 分钟。

  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 是否相等。

转载于:https://www.cnblogs.com/zhengbin/p/5657707.html

你可能感兴趣的文章
android一些细节问题
查看>>
KDESVN中commit时出现containing working copy admin area is missing错误提示
查看>>
利用AOP写2PC框架(二)
查看>>
【动态规划】skiing
查看>>
java定时器的使用(Timer)
查看>>
ef codefirst VS里修改数据表结构后更新到数据库
查看>>
boost 同步定时器
查看>>
[ROS] Chinese MOOC || Chapter-4.4 Action
查看>>
简单的数据库操作
查看>>
iOS-解决iOS8及以上设置applicationIconBadgeNumber报错的问题
查看>>
亡灵序曲-The Dawn
查看>>
Redmine
查看>>
帧的最小长度 CSMA/CD
查看>>
xib文件加载后设置frame无效问题
查看>>
编程算法 - 左旋转字符串 代码(C)
查看>>
IOS解析XML
查看>>
Python3多线程爬取meizitu的图片
查看>>
树状数组及其他特别简单的扩展
查看>>
zookeeper适用场景:分布式锁实现
查看>>
110104_LC-Display(液晶显示屏)
查看>>