原子引用 帶版本號的原子操作! 解決ABA問題,引入原子引用(樂觀鎖思想) AtomicStampedReference類解決ABA問題 package org.example.cas; import java.util.concurrent.TimeUnit; import java.util.c ...
原子引用
帶版本號的原子操作!
解決ABA問題,引入原子引用(樂觀鎖思想)
AtomicStampedReference類解決ABA問題
package org.example.cas;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;
//使用原子引用解決ABA問題
public class ABADemo {
public static void main(String[] args) {
//預設值 預設版本號(時間戳)
//如果泛型是一個包裝類,註意對象引用的問題
//正常在業務中裡面比較並交換的一般是一個個對象如User這種
AtomicStampedReference<Integer> atomic = new AtomicStampedReference<>(1,1);
new Thread(()->{
int stamp = atomic.getStamp();//獲得版本號
System.out.println("a1版本號=》"+stamp);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//atomic.compareAndSet 期待的值 更新的值 期待的版本號 更新的版本號
//當期待的值和期待的版本號都滿足期待時,就更新值和版本號
System.out.println(atomic.compareAndSet(1, 2, stamp, stamp + 1));
System.out.println("a2版本號=》"+atomic.getStamp());
System.out.println(atomic.compareAndSet(2, 1, atomic.getStamp(), atomic.getStamp() + 1));
System.out.println("a3版本號=》"+atomic.getStamp());
},"A").start();
//與樂觀鎖原理相同
new Thread(()->{
int stamp = atomic.getStamp();//獲得版本號
System.out.println("b1版本號=》"+stamp);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(atomic.compareAndSet(1, 2, stamp, stamp + 1));
System.out.println("b2版本號=》"+atomic.getStamp());
},"B").start();
}
}
所有相同類型的包裝類對象之間值的比較全部使用equals方法比較
Integer使用了對象緩存機制,預設範圍是-128至127,推薦使用靜態工廠方法valueOf獲取對象實例,而不是new,因為valueOf使用緩存,而new一定會創建新的對象分配新的記憶體空間;
說明:對於Integer var = ?在-128至127之間的賦值,Integer對象實在IntegerCache.cache產生,會復用已有對象,這個區間的Integer值可以直接使用==進行判斷,但是這個區間之外的所有數據,都會在堆上產生,並不會復用已有對象,這是一個大坑,推薦使用equals方法進行判斷。