參考文獻:https://www.cnblogs.com/cloudblogs/p/6440160.html

由於Lock是由JDK實現的,所以不像synchronize鎖的獲取和釋放都是由JVM控制的,Lock的獲取和釋放都需要手動進行,並且在發生異常時,不會自動釋放鎖。因此一般來說,使用Lock必須在try{}catch{}塊中進行,並且將釋放鎖的操作放在finally塊中進行,以保證鎖一定被被釋放,防止死鎖的發生。
1、lock() 獲取鎖與釋放鎖 ,如果鎖已被其他線程獲取,則進行等待。
1 Lock lock = ...; lock.lock(); 2 try{ 3 //處理任務 4 }catch(Exception ex){ 5 }finally{ 6 lock.unlock(); //釋放鎖 7 }
2、tryLock() 獲取鎖時有返回值可以得知獲取鎖操作是否成功
1 Lock lock = ...; 2 if(lock.tryLock()) { 3 try{ 4 //處理任務 5 }catch(Exception ex){ 6 }finally{ 7 lock.unlock(); //釋放鎖 8 } 9 }else { 10 //如果不能獲取鎖,則直接做其他事情 11 }
如果獲取成功則返回True,如果鎖被其他線程占用則返回FALSE,該方法會立即返回結果,不會讓線程一直處於等待狀態。
3、tryLock(long time,TimeUnit unit) 與tryLock() 類似,但是與tryLock立即返回結果不同,該方法在拿不到鎖的情況下回等待time時間,如果在限定時間內還是拿不到鎖就返回FALSE,如果在一開始或者等待時間內拿到鎖則返回TRUE。
4、lockInterruptibly()
通過這個方法嘗試獲取鎖時,如果線程正在等待獲取鎖,則該線程可以響應Thread.interrupt()中斷。synchronize對於沒有獲得鎖處於等待狀態的線程無法響應中斷。
1 public void method() throws InterruptedException { 2 lock.lockInterruptibly(); 3 try { //..... } 4 finally { lock.unlock(); } 5 }
lockInterruptibly方法必須放在try塊中或者在調用lockInterruptibly的方法外聲明拋出InterruptedException,推薦使用后者。
5、readWriteLock()
該鎖提升了讀操作的效率,不過要注意的是,如果有一個線程已經占用了讀鎖,則此時其他線程如果要申請寫鎖,則申請寫鎖的線程會一直等待釋放讀鎖。如果有一個線程已經占用了寫鎖,則此時其他線程如果申請寫鎖或者讀鎖,則申請的線程也會一直等待釋放寫鎖。
ReentrantLock lock = new ReentrantLock(true); ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);