一、什么是原子操作
不可被中斷的一個或者一系列操作、
CAS是Compare And Set的縮寫,是以一種無鎖的方式實現並發控制。在實際情況下,同時操作同一個對象的概率非常小,所以多數加鎖操作做的是無用功,CAS以一種樂觀鎖的方式實現並發控制。
二、實現原子操作的方式
Java可以通過鎖和循環CAS的方式實現原子操作。
三、CAS( Compare And Swap ) 為什么要有CAS?
Compare And Swap就是比較並且交換的一個原子操作,由Cpu在指令級別上進行保證。
為什么要有CAS:因為通過鎖實現原子操作時,其他線程必須等待已經獲得鎖的線程運行完以后才能獲得資源,這樣就會占用系統的大量資源
四、CAS包含哪些參數?
CAS包含三個參數:1、變量所在內存地址V;2、變量對應的值A;3、我們將要修改的值B。如果說V上的變量的值是A的話,就用B重新賦值,如果不是A,那就什么事也不做,操作的返回結果原值是多少。
循環CAS:在一個(死)循環【for(;;)】里不斷進行CAS操作,直到成功為止(自旋操作即死循環)。
五、CAS的原理
利用了現代處理器都支持的CAS的指令,循環這個指令,直到成功為止
六、CAS實現原子操作的三大問題
1、 ABA問題:其他的線程把值改成了B,很快改成了A,原子操作的線程發現值是A就修改,這樣會有問題。解決ABA,引入版本號:1A-》2C-》3A
2、 循環時間很長的話,cpu的負荷比較大
3、 對一個變量進行操作可以,同時操作多個共享變量有點麻煩
七、CAS線程安全(面試點)
通過硬件層面的阻塞實現原子操作的安全
八、原子操作類
jdk提供了許多根據CAS思路產生的原子操作類;總結下來可以分成以下幾類:
更新基本類型類:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
更新數組類:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
更新引用類型:AtomicReference,AtomicMarkableReference,AtomicStampedReference
原子更新字段類: AtomicReferenceFieldUpdater,AtomicIntegerFieldUpdater,AtomicLongFieldUpdater
例子:我們只是看其中的及格就行了
AtomicInteger (這里我們要注意incrementandget()和getAndincrement())
package pers.cc.cas; import java.util.concurrent.atomic.AtomicInteger; public class AtomicIntegerTest { /** * 定義一個線程安全的Integer並設定初始值為0 */ static AtomicInteger atomicInteger = new AtomicInteger(0); static int i = 0; public static void main(String[] args) throws InterruptedException { for (int j = 0; j < 100000; j++) { Thread addThread = new Thread(new Runnable() { @Override public void run() { // 原子的增加1 atomicInteger.incrementAndGet(); i++; } }); addThread.start(); } Thread.sleep(2000); System.out.println(atomicInteger.get()); System.out.println(i); } }
運行結果:
100000 99998
AtomicMarkableReference() 和 AtomicStampedReference()--區別?
--一個是通過版本號,一個是通過boolean值
參考文章: