天天看點

線程安全性以及JDK裡面的Atomic包線程安全性-原子性

文章目錄

  • 線程安全性-原子性
    • 定義
      • 表現在3個方面
          • 原子性:
          • 可見性:
          • 有序性:
    • JDK裡面的Atomic包
      • 運用AtomicInteger
        • IncrementAndGet源碼實作
          • 結論
          • 問題:一直進行對比循環影響性能怎麼辦?
          • 總結
    • AtomicReference(了解)
    • AtomicReferenceFieldUpdater(了解)
    • AtomicStampReference

線程安全性-原子性

定義

當多個線程通路某個類時,不管運作時環境采用何種排程方式或者這些程序講如何交替執行,主調代碼中都不需要任何格外的同步或協同這個類都能表現出正确的行為,那麼就稱這個類時線程安全的.

表現在3個方面

原子性:

提供了互斥通路,同一時刻隻能有一個線程對它進行操作

可見性:

一個線程對主記憶體的修改可以及時被其他線程觀察到

有序性:

一個線程觀察其他線程中的指令執行順序,由于指令重排序的存在,該觀察結果一般雜亂無序

JDK裡面的Atomic包

Atomic包裡面很多類是運用 CAS 來完成原子性的

運用AtomicInteger

在并發環境下實作count++操作

public static int count = 0;

count++

變成

public static AtomicInteger count = new AtomicInteger (0);
	count.incrementAndGet();//先做增加操作 再擷取值
	//或者 count.getAndIncrement 先擷取值再增加
           

IncrementAndGet源碼實作

線程安全性以及JDK裡面的Atomic包線程安全性-原子性

getAndaddInt方法

線程安全性以及JDK裡面的Atomic包線程安全性-原子性

getAndaddInt方法的作用

var1 代表目前對象

var2 代表目前傳來的值

var5 代表從底層傳來的值

var4 是 1

如果目前傳來的值與底層傳來的值相同的話,就把他更新成var5+var4 的值

compareAndSwapInt方法 CAS

線程安全性以及JDK裡面的Atomic包線程安全性-原子性

注意

native關鍵字表示 和本地C代碼進行互操作的API

結論

拿目前的值與底層的值進行對比,目前的值和底層的值他倆一樣的時候才進行操作.

問題:一直進行對比循環影響性能怎麼辦?

LongAdder可以将單點的壓力分散到各個節點上

總結

在高并發的情況下,用LongAdder,在并發要求不是很高的情況下,用AtomicInteger.

當需要生成序列号這種準确的數值的話,考慮使用AtomicXXX(LongAdder沒有Atomic準确)

AtomicReference(了解)

AtomicReferenceFieldUpdater(了解)

作用 :更新一個指定的類的某一字段的值

//注意:值為volatile
@Getter
public volatile int count = 100;

           

AtomicStampReference

作用: 通過對每一次操作加入版本号,解決CAS的ABA問題

ABA就是 一個數原本是A,先被改成了B,又被改回了A,系統判定該數沒有變化的錯誤