Java併發的CAS&AQS技術
阿新 • • 發佈:2018-12-10
細說CAS技術
一、CAS理論:
- CAS是Java的lock-free機制的實現。
- CAS 是相等即可設定,我理解是一種概念。配合上loop即可在高併發時使用,可以理解為一種樂觀鎖。
- CAS會有ABA問題出現。個人理解結果有兩種,(1)同樣的value更新到同樣的值,是正確的結果。(2)如果出現錯誤,那是compare的value選擇錯誤,應該選擇唯一性的值,或者加入tag。
發生了 A -> B -> A 的更新,僅僅判斷數值是 A,可能導致不合理的修改操作。針對這種情況,Java 提供了 AtomicStampedReference 工具類,通過為引用建立類似版本號(stamp)的方式,來保證 CAS 的正確性,具體用法請參考這裡的
- cas的應用場景為短時間鎖和無鎖的安全保障,如果變數長時間被鎖,不斷loop可能造成cpu 效能飆升。
Lock-Free無鎖程式設計是指在不使用鎖的情況下,在多執行緒環境下實現多變數的同步。即在沒有執行緒阻塞的情況下實現同步。這樣可以避免競態、死鎖等問題。
二、AtomicInteger的CAS應用
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;//地址偏移量
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value" ));//獲取地址偏移量
} catch (Exception ex) { throw new Error(ex); }
}
private volatile int value;//僅僅用作get和原子性set
public final int getAndAdd(int delta) {
return unsafe.getAndAddInt(this, valueOffset, delta);//由unsafe呼叫cpu指令,更新value的值。
}
三、AbstractQueuedSynchronizer併發基礎抽象類。
AQS是 Java 併發包中,實現各種同步結構和部分其他組成單元(如執行緒池中的 Worker)的基礎。
以ReentrantLock為例,內部鎖就是基於AbstractQueuedSynchronizer實現的。
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
/** Synchronizer providing all implementation mechanics */
private final Sync sync;
/**
* Base of synchronization control for this lock. Subclassed
* into fair and nonfair versions below. Uses AQS state to
* represent the number of holds on the lock.
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;