一、synchronized:它是java中的一個關鍵字,它能夠把任意一個非NULL的對象看成鎖。java
1)做用於方法時,鎖住的是對象的實例(this);緩存
2)看成用於靜態方法時,鎖住的是Class實例,又由於Class的相關數據存儲在永久帶PermGen(jdk1.8則是metaspace),永久帶是全局共享的,所以靜態方法鎖至關於類的一個全局鎖,會鎖全部調用該方法的線程;併發
3)synchronized做用於一個對象實例時,鎖住的是全部以該對象爲鎖的代碼塊。性能
二、Lock:Lock有一個實現類:ReentrantLock,它實現了Lock裏面的方法,可是使用Lock的時候必須注意它不會像synchronized執行完成以後或者拋出異常以後自動釋放鎖,而是須要你主動釋放鎖,因此咱們必須在使用Lock的時候加上try{}catch{}finally{}塊,而且在finally中釋放佔用的鎖資源。this
Lock和synchronized最大的區別就是當使用synchronized,一個線程搶佔到鎖資源,其餘線程必須等待;而使用Lock,一個線程搶佔到鎖資源,其餘的線程能夠不等待或者設置等待時間,實在搶不到能夠去作其餘的業務邏輯。spa
三、ReadWriteLock(讀讀共享,其餘全互斥):它能夠實現讀寫鎖,當讀取的時候線程會得到read鎖,其餘線程也能夠得到read鎖同時併發的去讀取,可是寫程序運行獲取到write鎖的時候,其餘線程是不能進行操做的,由於write是排它鎖,而上面介紹的兩種無論你是read仍是write沒有搶到鎖的線程都會被阻塞或者中斷,它也是個接口,裏面定義了兩種方法readLock()和readLock(),他的一個實現類是ReentrantReadWriteLock。線程
關於讀寫鎖的一個緩存例子CacheDemo:code
package resource.java.ordinary.mul.thread; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 一個緩存demo,讀寫鎖例子,實現讀和寫互斥、寫和寫互斥,但有能夠多個併發的讀,可提升系統性能 * * @author xiao */ public class CacheDemo { // 數據 private Map<String, Object> cache = new HashMap<>(); // 讀寫鎖 private ReadWriteLock rwl = new ReentrantReadWriteLock(); public Object getData(String key) { // 上讀鎖,多個讀時能夠併發,不會形成對數據的破壞 rwl.readLock().lock(); Object value = null; try { value = cache.get(key); // 若是數據爲空 if (value == null) { // 釋放讀鎖上寫鎖,上寫鎖後,數據不能被讀 rwl.readLock().unlock(); rwl.writeLock().lock(); try { // 此處判斷是爲防止多個線程同時進入到這裏時,多個線程對數據進行重複寫 if (value == null) { // 若是沒有數據,則去查DB獲取數據 value = "XXX"; } } finally { // 讀取數據後釋放寫鎖 rwl.writeLock().unlock(); } // 獲取完數據後,恢復讀鎖,從新讀取數據 rwl.readLock().lock(); } } finally { // 從新讀取數據釋放讀鎖 value = cache.get(key); rwl.readLock().unlock(); } return value; } }