02.第二階段、實戰Java高併發程序設計模式-4.無鎖

1. 無鎖類的原理詳解算法

1.1. CAS數組

CAS算法的過程是這樣:它包含3個參數CAS(V,E,N)。V表示要更新的變量,E表示預期值,N表示新值。僅當V 值等於E值時,纔會將V的值設爲N,若是V值和E值不一樣,則說明已經有其餘線程作了更新,則當前線程什麼 都不作。最後,CAS返回當前V的真實值。CAS操做是抱着樂觀的態度進行的,它老是認爲本身能夠成功完成 操做。當多個線程同時使用CAS操做一個變量時,只有一個會勝出,併成功更新,其他均會失敗。失敗的線程 不會被掛起,僅是被告知失敗,而且容許再次嘗試,固然也容許失敗的線程放棄操做。基於這樣的原理,CAS 操做即時沒有鎖,也能夠發現其餘線程對當前線程的干擾,並進行恰當的處理。安全

1.2. CPU指令線程

cmpxchg
/*
accumulator = AL, AX, or EAX, depending on whether
a byte, word, or doubleword comparison is being performed */
if(accumulator == Destination) {orm

ZF = 1;對象

Destination = Source; }接口

else {
ZF = 0;rem

accumulator = Destination; }get

2. 無鎖類的使用io

2.1. AtomicInteger

2.1.1. 概述 Number

2.1.2. 主要接口

public

final

int

get()

 

//取得當前值 //設置當前值

//設置新值,並返回舊值

public

final

void

set(int

newValue)

 

public

final

int

getAndSet(int

newValue)

 

public

final

boolean

compareAndSet(int

expect,

int

u)

//若是當前值爲expect,則設置爲u

public

final

int

getAndIncrement()

//當前值加1,返回舊值 //當前值減1,返回舊值

//當前值增長delta,返回舊值 //當前值加1,返回新值 //當前值減1,返回新值

//當前值增長delta,返回新值

public

final

int

getAndDecrement()

 

public

final

int

getAndAdd(int

delta)

 

public

final

int

incrementAndGet()

 

public

final

int

decrementAndGet()

 

public

final

int

addAndGet(int

delta)

2.1.3. 主要接口的實現

2.2. Unsafe

2.2.1. 概述

非安全的操做,好比: 根據偏移量設置值 park() 底層的CAS操做

非公開API,在不一樣版本的JDK中, 可能有較大差別

2.2.2. 主要接口

//得到給定對象偏移量上的int值
public native int getInt(Object o, long offset); //設置給定對象偏移量上的int值
public native void putInt(Object o, long offset, int x); //得到字段在對象中的偏移量
public native long objectFieldOffset(Field f); //設置給定對象的int值,使用volatile語義
public native void putIntVolatile(Object o, long offset, int x); //得到給定對象對象的int值,使用volatile語義
public native int getIntVolatile(Object o, long offset); //和putIntVolatile()同樣,可是它要求被操做字段就是volatile類型的 public native void putOrderedInt(Object o, long offset, int x);

2.3. AtomicReference

2.3.1. 概述

對引用進行修改 是一個模板類,抽象化了數據類型

2.3.2. 主要接口

get()
set(V) compareAndSet() getAndSet(V)

2.4. AtomicStampedReference

2.4.1. 概述

ABA問題

2.4.2. 主要接口

//比較設置 參數依次爲:指望值 寫入新值 指望時間戳 新時間戳
public boolean compareAndSet(V expectedReference,V newReference,int expectedStamp,int newStamp) //得到當前對象引用
public V getReference()
//得到當前時間戳
public int getStamp()
//設置當前對象引用和時間戳
public void set(V newReference, int newStamp)

2.5. AtomicIntegerArray

2.5.1. 概述

支持無鎖的數組

2.5.2. 主要接口

//得到數組第i個下標的元素
public final int get(int i)
//得到數組的長度
public final int length()
//將數組第i個下標設置爲newValue,並返回舊的值
public final int getAndSet(int i, int newValue) //進行CAS操做,若是第i個下標的元素等於expect,則設置爲update,設置成功返回true public final boolean compareAndSet(int i, int expect, int update)

//將第i個下標的元素加1
public final int getAndIncrement(int i) //將第i個下標的元素減1
public final int getAndDecrement(int i) //將第i個下標的元素增長delta(delta能夠是負數) public final int getAndAdd(int i, int delta)

2.6. AtomicIntegerFieldUpdater

2.6.1. 概述

讓普通變量也享受原子操做

2.6.2. 主要接口 AtomicIntegerFieldUpdater.newUpdater()

incrementAndGet()

2.6.3. 小說明

1. Updater只能修改它可見範圍內的變量。由於Updater使用反射獲得這個變量。若是變量不可見,就會出錯。

好比若是score申明爲private,就是不可行的。
2. 爲了確保變量被正確的讀取,它必須是volatile類型的。若是咱們原有代碼中未申明這個類型,那麼簡單得 申明一下就行,這不會引發什麼問題。

3. 因爲CAS操做會經過對象實例中的偏移量直接進行賦值,所以,它不支持static字段(Unsafe. objectFieldOffset()不支持靜態變量)。

3. 無鎖算法詳解

3.1. 無鎖的Vector實現

相關文章
相關標籤/搜索