標籤:
內建鎖 sychronized跟volatile;
1.volatile本質是在告訴jvm當前變數在寄存器(工作記憶體)中的值是不確定的,需要從主存中讀取;synchronized則是鎖定當前變數,只有當前線程可以訪問該變數,其他線程被阻塞住。
2.volatile僅能使用在變數層級;synchronized則可以使用在變數、方法、和類層級的
3.volatile僅能實現變數的修改可見度,並能保證原子性;而synchronized則可以保證變數的修改可見度和原子性
4.volatile不會造成線程的阻塞;synchronized可能會造成線程的阻塞。
5.volatile標記的變數不會被編譯器最佳化;synchronized標記的變數可以被編譯器最佳化
顯示鎖
顯示鎖
在JDK5之前,可使用的同步機制只有synchronized 關鍵字和volative變數,JDK5增加了一種新的鎖機制:ReentrantLock, ReentrantLock並不是替代內建鎖的方法,而是當內建鎖機制不適用時作為一種可選擇的進階功能。
JDK5提供的鎖工具類都在java.util.concurrent.locks包下,有Condition、Lock、ReadWriteLock等介面:
Lock : 介面支援那些語義不同(重入、公平等)的鎖規則,可以在非阻塞式結構的上下文(包括 hand-over-hand 和鎖重排演算法)中使用這些規則。主要的實現是 ReentrantLock 。
1 public class Counter{ 2 private Lock lock = new Lock(); 3 private int count = 0; 4 5 public int inc(){ 6 lock.lock(); 7 int newCount = ++count; 8 lock.unlock(); 9 return newCount;10 }11 }
lock()方法會對Lock執行個體對象進行加鎖,因此所有對該對象調用lock()方法的線程都會被阻塞,直到該Lock對象的unlock()方法被調用。
ReadWriteLock : 讀寫鎖介面以類似方式定義了一些讀取者可以共用而寫入者獨佔的鎖。此包只提供了一個實現,即 ReentrantReadWriteLock ,因為它適用於大部分的標準用法上下文。但程式員可以建立自己的、適用於非標準要求的實現。
Condition : 介面描述了可能會與鎖有關聯的條件變數。這些變數在用法上與使用 Object.wait 訪問的隱式監視器類似,但提供了更強大的功能。需要特別指出的是,單個 Lock 可能與多個 Condition 對象關聯。
在大多數情況下,顯示鎖都能很好的工作,但有些局限性,如無法中斷一個正在等待擷取鎖的線程,或者無法在請求擷取一個鎖時無限的等待下去。Lock提供了一種無條件的、可輪詢的、定時的以及可中斷的鎖擷取操作,所有加鎖和解鎖的方式都是顯示的。下面代碼給出了Lock介面使用的標準形式,必須在finally中釋放鎖:
1 Lock lock = new ReentrantLock(); 2 ... 3 lock.lock();//顯示加鎖 4 try{ 5 ... 6 }finally{ 7 //顯示釋放鎖 8 lock.unlock(); 9 }
boolean tryLock()介面實現可定時與可輪詢擷取鎖的實現,與無條件擷取鎖的模式相比,它具有更完善的錯誤恢複機制,在內建鎖中,死結是一種嚴重的問題,恢複程式的唯一方法就是重啟應用,而防止死結的方法就是在構造程式時避免出現不一致的鎖順序。可定時與可輪詢提供了另一種方式:避免死結的發生。下面代碼實現了可輪詢擷取鎖,如果不能同時獲得兩個鎖,那麼就退回重試:
1 public boolean transferMoney(Account fromAcct, Account toAcct) { 2 while (true) { 3 if (fromAcct.lock.tryLock()) { 4 try { 5 if (toAcct.lock.tryLock()) { 6 try { 7 ... 8 } 9 finally { 10 toAcct.lock.unlock(); 11 } 12 } 13 } 14 finally { 15 fromAcct.lock.unlock(); 16 } 17 } 18 } 19 }
讀寫鎖:由JVM控制,保證讀跟寫的互斥。
下面為用讀-寫鎖來封裝的Map類
1 package thread; 2 3 import com.sun.org.apache.bcel.internal.generic.NEW; 4 5 import java.util.Map; 6 import java.util.concurrent.locks.Lock; 7 import java.util.concurrent.locks.ReadWriteLock; 8 import java.util.concurrent.locks.ReentrantReadWriteLock; 9 10 /** 11 * @description 12 * 13 * @author chenzehe 14 * @email [email protected] 15 * @create 2013-1-9 下午09:05:58 16 */ 17 18 public class ReadWriteMap<K, V> { 19 private final Map<K, V> map; 20 private final ReadWriteLock lock = new ReentrantReadWriteLock(); 21 private final Lock r = lock.readLock(); 22 private final Lock w = lock.writeLock(); 23 24 public ReadWriteMap(Map<K, V> map) { 25 this.map = map; 26 } 27 28 public V put(K key, V value) { 29 w.lock(); 30 try { 31 return map.put(key, value); 32 } 33 finally { 34 w.unlock(); 35 } 36 } 37 38 public V get(Object key) { 39 r.lock(); 40 try { 41 return map.get(key); 42 } 43 finally { 44 r.unlock(); 45 } 46 } 47 }
java中的鎖