顯式鎖 一、Lock與ReentrantLock Lock提供了一種無條件的、可輪詢的、定時的以及可中斷的鎖獲取操作,所有的加鎖和解鎖方法都是顯式的 ReentrantLock實現了Lock:並提供了和synchronized相同的記憶體語義;同時提供了可重入的加鎖語義 1.基本語義: 2.輪詢鎖與定 ...
顯式鎖
一、Lock與ReentrantLock
Lock提供了一種無條件的、可輪詢的、定時的以及可中斷的鎖獲取操作,所有的加鎖和解鎖方法都是顯式的
ReentrantLock實現了Lock:並提供了和synchronized相同的記憶體語義;同時提供了可重入的加鎖語義
1.基本語義:
void LockDefinition() { Lock lock = new ReentrantLock(); try { //do someting //更新對象狀態,捕獲異常;併在必要時恢復不變性條件 } finally { //finally中釋放鎖 lock.unlock(); } }
2.輪詢鎖與定時鎖
lock.tryLock([Long,TimeUnit]):嘗試獲取鎖,帶上時間就是定時鎖
3.可中斷的鎖獲取操作
lock.lockInterruptibly();
二、公平性
ReentrantLock可以創造公平鎖(已請求順序獲取鎖)和非公平鎖(可插隊)。
插隊:當一個線程請求非公平鎖,如果在發出請求的同時該鎖的狀態可用,那麼這個線程不會放入隊列,會跳過隊列中所有的等待線程並獲得鎖;
註意:非公平鎖並不提倡插隊,但無法防止插隊;而公平鎖則是會放入隊列中順序執行
非公平鎖在競爭激烈時速度比公平鎖快:原因是在恢復一個在隊列中的線程與該線程開始運行之間存在嚴重的延遲
三、讀-寫鎖
ReentrantLock是標準的互斥鎖,但是在某些場景如:讀讀可並行無法實現
ReadWriteLock讀寫鎖:實現ReentrantReadWriteLock:方法readLock讀鎖和writeLock寫鎖
1、交互和實現方式
釋放優先:當一個寫鎖被釋放,而隊列中同時存在讀和寫,那麼應該優先選擇讀,寫,還是最先發出請求的線程?
讀線程插隊:當前讀鎖,有寫鎖在等待,那麼後面來的讀鎖要不要插隊直接讀?如果直接讀會提高併發但是會可能造成寫饑餓獲取不到
重入性:讀鎖和寫鎖是否可重入?
降級:寫鎖,能否在不釋放鎖情況下獲取讀鎖,使該線程的鎖降級?
升級:讀鎖能否優先於其他等待線程升級為寫鎖?如果兩個線程試圖同時升級為寫鎖,那麼容易造成死鎖
適用於:讀取操作為主的數據結構