synchronized、Lock、ReentrantLock、ReadWriteLock
synchronized:同步鎖,是java內置的關鍵字。當一個線程A執行到被synchronized修飾的方法時,其他線程B如果也要執行這個方法,那麽B只能等A執行完方法釋放鎖後才能獲取資源鎖執行synchronized方法塊。
synchronized釋放鎖的情況
1,執行完改代碼塊,釋放鎖
2,執行時發生異常,jvm自動釋放
lock:是一個類,通過這個類可以實現同步訪問
lock和synchronized最大不同點。lock釋放鎖需要手動釋放,如果沒有手動釋放則會導致死鎖的現象
而synchronized則不需要手動釋放,會自動釋放鎖
lock可以知道線程有沒有獲取到鎖,而synchronized則不能
lock可以提供機制使多個線程同時進行讀或者寫的操作,而synchronized則不能
tryLock()方法有返回值,表示用來嘗試獲取鎖,如果成功則返回true,如果失敗則返回false。它都是立即返回的。在拿不到鎖時不會等待
Lock lock = ...; if(lock.tryLock()) { try{ //處理任務 }catch(Exception ex){ }finally{ lock.unlock(); //釋放鎖 } }else { //如果不能獲取鎖,則直接做其他事情 }
lockInterruuptibly()方法:可以通過這個方法獲取鎖,如果線程正在等待獲取鎖,則這個線程能夠響應中斷
例子:a獲取了鎖,而b在等待獲取鎖,那麽b可以調用interuuptibly()方法結束等待
public void method() throws InterruptedException { lock.lockInterruptibly(); try { //..... } finally { lock.unlock(); } }
ReentrantLock 重入鎖
1. ReenTrantLock可以指定是公平鎖還是非公平鎖。而synchronized只能是非公平鎖。所謂的公平鎖就是先等待的線程先獲得鎖。
2. ReenTrantLock提供了一個Condition(條件)類,用來實現分組喚醒需要喚醒的線程們,而不是像synchronized要麽隨機喚醒一個線程要麽喚醒全部線程。
3. ReenTrantLock提供了一種能夠中斷等待鎖的線程的機制,通過lock.lockInterruptibly()來實現這個機制。
ReadWriteLock 讀寫鎖
實現了ReentrantLock接口
讀寫鎖,可以通過讀方法或者寫方法使多個線程同時進行讀或者寫,提高線程效率
註意,讀和寫是互斥的,如果a獲取到讀方法的鎖,如果他在要去獲取寫方法的鎖那麽他是獲取不到的
synchronized、Lock、ReentrantLock、ReadWriteLock