特色:html
不適用的場景:java
場景一:變量用於非原子的操做編程
private volatile int count; public void increment() { count++; }
++操做不是原子操做,volatile不能保證數據的原子性。若是須要原子的讀寫操做,可使用concurrent包裏的AtomicXxx類。緩存
場景二:變量與其它變量在一個不變式條件中(以下:lower < upper是一個不變式)多線程
public class NumberRange { private int lower, upper; public int getLower() { return lower; } public int getUpper() { return upper; } public void setLower(int value) { if (value > upper) throw new IllegalArgumentException(...); lower = value; } public void setUpper(int value) { if (value < lower) throw new IllegalArgumentException(...); upper = value; } }
多線程狀況下,若是兩個線程同時修改lower和upper,這時候即便是volatile也不能保證lower < upper這個不變式始終成立。併發
場景三:變量須要加鎖訪問的狀況,由於已經用了鎖,volatile顯然是多餘的。jvm
特色:性能
一種輕量級的鎖,基於硬件CPU指令實現。這是一種樂觀鎖,假設不會產生衝突而不加鎖地進行操做,若是操做失敗就不停地重試,直到操做成功。是一種非阻塞的機制。優化
原理:提供3個操做數,分別是內存位置V,原有的預期值A,要修改的新值B,只有當A=V時,才把V的值修改成B,不然,一直重試,直到成功。.net
public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
問題:
特色:
特色:
特色:
無論是synchronized仍是ReentrantLock,都是強類型的互斥鎖,併發狀況下的性能會受影響。可是在一些應用場景下,可能讀操做要多於寫操做,在沒有寫操做的時候,若是用這種強互斥鎖的話,會嚴重影響讀線程的性能。因此能夠考慮用ReentrantReadWriteLock來代替上面的強互斥鎖,讓多個讀線程能夠併發地訪問被保護的對象,提升吞吐量。PS:能夠在LinkedHashMap上使用ReentrantReadWriteLock來實現高性能的LRU Cache.
另一種讀寫鎖的實現是經過volatile(保證讀可見) + synchronized(保證寫原子性)來實現。
參考資料:
推薦閱讀: