AtomicInteger

AtomicInteger 是对 int 类型的一个封装,提供了原子性的访问和更新操作,其原子性操作的实现是基于CAS(compare-and-swap)技术。

AtomicInteger 提供一种线程安全的加减操作接口。

看看 AtomicInteger 源代码:

private volatile int value;

volatile 关键字是保证AtomicInteger 线程安全的根源。

volatile 修饰的成员变量,在每次被线程访问时,都强迫从共享内存重新读取该成员的值,而且,当成员变量值发生变化时,强迫将变化的值重新写入共享内存,这样两个不同的线程在访问同一个共享变量的值时,始终看到的是同一个值。

Java语言规范指出:为了获取最佳的运行速度,允许线程保留共享变量的副本,当这个线程进入或者离开同步代码块时,才与共享成员变量进行比对,如果有变化再更新共享成员变量。这样当多个线程同时访问一个共享变量时,可能会存在值不同步的现象。

而volatile这个值的作用就是告诉VM:对于这个成员变量不能保存它的副本,要直接与共享成员变量交互。

建议:当多个线程同时访问一个共享变量时,可以使用volatile,而当访问的变量已在synchronized代码块中时,不必使用。

缺点:使用volatile将使得VM优化失去作用,导致效率较低,所以要在必要的时候使用。

CAS(compare-and-swap)

所谓CAS,表示的是一系列操作的集合,获取当前值,进行运算,利用CAS 指令试图进行更新。

如果当前数值未变,表示没有其他线程进行并发修改,则成功更新。

否则,可能出现不同的选择,要么进行重试,要么就返回一个成功或者失败的结果。

CAS就是Compare and Swap的意思,比较并操作。

CAS有3个操作数:

其实CAS的过程也是挺简单的,来一发流程图吧。

atomic 指令(AtomicInteger底层实现原理是什么)(1)

CAS简而言之就是:CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

CAS 是Java并发中所谓 lock-free 机制的基础。

CAS 也并不是没有副作用,试想,其常用的失败重试机制,隐含着一个假设,即竞争情况是短暂的。大多数应用场景下,确实大部分重试只会发生一次就获得了成功,但是总是有意外情况,所以在有需要的时候,还是要考虑限制自旋的次数,以免过度消耗CPU。

AbstractQueuedSynchronizer(AQS)

是Java 并发包中,实现各种同步结构的基础。

AQS 内部数据和方法,可以简单拆分为:

利用AQS 实现一个同步结构,至少需要实现2个基本类型的方法,分别是 acquire 操作,获取资源的独占权;还有就是 release 操作,释放对某个资源的独占。

,