java的鎖機制,synchronize與Lock比較
阿新 • • 發佈:2019-01-29
以前執行緒同步只知道synchronize關鍵字,後來才知道還有個lock,為什麼還要有個lock來實現同步呢
synchronized的侷限性
- 佔有鎖的執行緒等待IO或者其他原因被阻塞,沒有釋放鎖的情況下,其他執行緒一直阻塞
- 多個執行緒同時讀寫檔案的時候,讀和讀操作也會發生衝突
- 我們沒有辦法知道當前我們的執行緒是否成功獲取了鎖,只能傻傻的等待
有這些限制所有其他的同步機制來解決,所以就有了lock,lock常用的兩個介面和兩個實現
第一個,Lock介面,我們來看下它的定義
package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
這幾個方法的作用分別是
- lock()獲取鎖,沒有獲取一直等待,無返回值
- lockInterruptibly()獲取鎖一直等待,無返回值,但是可以被thread.interrupt()方法中斷,丟擲異常
- tryLock()獲取鎖,不等待,返回是否獲取成功
- tryLock(long time, TimeUnit unit)獲取鎖,沒有獲取等待指定時間,返回是否獲取成功,等待時候可以被thread.interrupt()方法中斷,丟擲異常
- unlock()釋放鎖
- newCondition()實現執行緒間的互動,與Object的wait,notify,notify對應
生產者消費者兩種實現方式
synchronize與lock的鎖的釋放
- synchronize滿足下列三個條件之一釋放鎖
- 佔有鎖的執行緒執行完畢
- 佔有鎖的執行緒異常退出
- 佔有鎖的執行緒進入waiting狀態釋放鎖
- Lock必須呼叫unlock()方法
Lock介面的唯一實現ReentrantLock,意思是可重入鎖,可重入鎖後面介紹
第二個,ReadWriteLock介面,我們來看下它的定義
package java.util.concurrent.locks;
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading
*/
Lock readLock();
/**
* Returns the lock used for writing.
*
* @return the lock used for writing
*/
Lock writeLock();
}
註釋寫的很清楚,為了解決兩個執行緒同時讀操作還互斥的問題
ReentrantReadWriteLock()為ReadWriteLock 介面的實現
一些鎖的概念
- 可重入鎖,同一個執行緒呼叫同鎖的多個程式碼塊和方法不會重複加鎖,sy和Lock和readwritelock都是可重入鎖
- 可中斷鎖 在等待的過程中可中斷,lockInterruptibly()獲取的就是可中斷鎖,中斷會丟擲異常
- 公平鎖,上面介紹的兩個鎖都可以加入Boolean型的構造引數,預設是非公平鎖,多個執行緒同時等待,當前執行緒執行完畢,隨機執行下個執行緒,公平鎖即先到先執行
- 讀寫鎖,讀寫鎖,即讀鎖和寫鎖是分開的