JUC下的AtomicInteger——CAS

一、简介

JUC下的atomic包,提供了一系列原子操作的包装类。利用此包下的类,可以实现常见如i++的原子操作。包下的类如下:

二、AtomicInteger

其中AtomicInteger是一个常用的类,可以实现自增或者增加任意数的原子操作。其中实现的关键方式是使用UnSafe类以及CAS思想。以下为AtomicInteger的类:

而AtomicInteger的自增方法getAndIncrement,通过调用UnSafe类的getAndAddInt()来实现。

三、CAS介绍

CAS(compare and swap),也就是比较并交换。概括而言就是如果内存值==预期值,则内存值=更新值。

首先,CAS是乐观锁的一种实现方式,他采用的是自旋锁的思想,是一种轻量级的锁机制。即每次判断我的预期值和内存中的值是不是相同,如果不相同则说明该内存值已经被其他线程更新过了,因此需要拿到该最新值作为预期值,重新判断。而该线程不断的循环判断是否该内存值已经被其他线程更新过了,这就是自旋的思想。

在UnSafe类中,使用的就是自旋锁的方式实现原子操作。

四、CAS的缺点

CAS使用自旋锁的方式,由于该锁会不断循环判断,因此不会类似synchronize线程阻塞导致线程切换。但是不断的自旋,会导致CPU的消耗,在并发量大的时候容易导致CPU跑满。

其次,是CAS存在ABA问题。

五、ABA问题

ABA问题,即某个线程将内存值由A改为了B,再由B改为了A。当另外一个线程使用预期值去判断时,预期值与内存值相同,误以为该变量没有被修改过而导致的问题。

解决ABA问题的主要方式,通过使用类似添加版本号的方式,来避免ABA问题。如原先的内存值为(A,1),线程将(A,1)修改为了(B,2),再由(B,2)修改为(A,3)。此时另一个线程使用预期值(A,1)与内存值(A,3)进行比较,只需要比较版本号1和3,即可发现该内存中的数据被更新过了。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章