Java高並發程序設計(十)--無鎖
阿新 • • 發佈:2018-08-07
期望 spa 策略 edt sys .net () .html pac
鎖是一種悲觀策略,總是覺得會出問題,所以小心翼翼地操作。
無鎖是一種樂觀策略,總是假設不會出現問題,如果出現問題,那就重新操作。無鎖一般使用CAS作為策略。
比較交換CAS:
CAS算法包括三個參數:需要更新的變量,預期值,更新值。只有當需要更新的值等於預期值時,說明其他線程沒有對它進行操作,使需要更新值等於更新值。
在java.util.concurrent.atomic中,實現了很多無鎖的類型:
用AtomicInteger寫個小例子:
public class demo implements Runnable{ static AtomicInteger ai=new AtomicInteger();public static void main(String[] args) throws InterruptedException { ExecutorService es=Executors.newFixedThreadPool(10); for(int i=0;i<10;i++) { es.submit(new demo()); } Thread.sleep(1000); System.out.println(ai); } public void run() {for(int i=0;i<100;i++) { ai.incrementAndGet(); } } }
沒有加鎖的情況下,輸出結果為1000,AtomicXX的操作都是具有原子性的,具體方法可以自己看API。
我們接下來看一下incrementAndGet()方法:
public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1;if (compareAndSet(current, next)) return next; } }
如上面對CAS算法的描述一樣,不斷嘗試直到成功,進入compareAndSet():
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
調用了unsafe類的compareAndSwapInt,只需要知道他的大概意思就行,通過字段偏移量找到位置,通過期望值與待更新值的對比決定要不要更新。
Java高並發程序設計(十)--無鎖