原子操作

無鎖

通過CAS+volatile來實現

while (true) {
int prev = balance.get();
int next = prev - amount;
if (balance.compareAndSet(prev, next)) {
break;
 }
 }
// 可以簡化為下面的方法
// balance.addAndGet(-1 * amount);

CAS特點

  1. 基于樂觀鎖設計,不怕修改共享變量,修改了也沒事,繼續(xù)等待就可以。
  2. synchronized是基于悲觀鎖,鎖住操作,會導致線程狀態(tài)切換,也會用戶態(tài)到內核態(tài)切換。效率較差。
  3. CAS需要重試,CPU空轉,如果是單核cpu或者線程數量大于cpu核心數,也會導致線程狀態(tài)一直切換,效率反而變低。

CAS+volatile

cas+volatitle組合實現樂觀鎖,volatile只能保證可見性,和一部分的有序性,并不能防止指令重排序。通過cas+volatitle的組合實現樂觀鎖。

JUC中的原子類

原子整數

基本的i++,i--,等操作,還可以是表達式,表達式可以保證是原子操作。
AtomicBoolean
AtomicInteger
AtomicLong

原子引用

通過無鎖的方式更新變量對象的引用值。
AtomicReference//不能解決ABA問題
AtomicStampedReference//增加版本號,可以追蹤每次修改
AtomicMarkableReference//增加標識,可以看到是否修改,但不追蹤整個過程

原子數組

AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray

字段更新器

線程安全的方式更新對象中的某個字段
需要配合volatitle使用:字段必須是volatile修飾的,否則拋出異常
AtomicReferenceFieldUpdater
AtomicIntegerFieldUpdater
AtomicLongFieldUpdater

原子累加器

性能更好

Unsafe

Unsafe 對象提供了非常底層的,操作內存、線程的方法,Unsafe 對象不能直接調用,只能通過反射獲得

Unsafe實現CAS

class Student {
volatile int id;
volatile String name; }
Unsafe unsafe = UnsafeAccessor.getUnsafe();
Field id = Student.class.getDeclaredField("id");
Field name = Student.class.getDeclaredField("name");
// 獲得成員變量的偏移量
long idOffset = UnsafeAccessor.unsafe.objectFieldOffset(id);
long nameOffset = UnsafeAccessor.unsafe.objectFieldOffset(name);
Student student = new Student();
// 使用 cas 方法替換成員變量的值
UnsafeAccessor.unsafe.compareAndSwapInt(student, idOffset, 0, 20); // 返回 true
UnsafeAccessor.unsafe.compareAndSwapObject(student, nameOffset, null, "張三"); // 返回 true
System.out.println(student);
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容