ReentranLock底層原理分析

1 J.U.C簡介

  • java.util.concurrent 簡稱,java并發工具包
  • 線程池
  • 阻塞隊列
  • 計時器/同步器
  • 并發集合

2 Lock的基本使用

  • synchronized 不夠靈活,鎖的釋放無法人為控制,只能等待同步代碼塊執行完成或發生異常
  • Lock java.util.concurrent.locks 包下的接口,提供了鎖的獲得與釋放的接口方法,在JUC中存在眾多實現
    image.png

3 ReentranLock重入鎖

  • 同一線程 通過Lock.lock()獲得重入鎖,當此線程再次調用時不會被阻塞可以進入,即:同一線程"一次鎖定多次進入",其它線程此時調用進行阻塞
  • synchronized 也支持重入
  • ReentranLock重入鎖的設計目的是為了解決死鎖
public class ThreadDemo1 {

    public synchronized void func1(){//獲取對象鎖
        System.out.println("func1");
        func2();
    }

    public void func2(){
        synchronized (this){//同一線程,同一把鎖允許重入,增加重入次數,并沒有死鎖
            System.out.println("func2");
        }//同步代碼執行完成,減少重入次數
    }

    public static void main(String[] args) {
        ThreadDemo1 demo1 = new ThreadDemo1();
        demo1.func1();
    }
}

public class ThreadDemo2 {
    //重入鎖
    static Lock LOCK = new  ReentrantLock();
    
    public void func1(){
        LOCK.lock();//獲得重如鎖
        //....
        LOCK.unlock();//釋放重入鎖
    }
}

4 讀寫鎖ReentrantReadWriteLock

  • 適用于讀多寫少的操作,例如緩存更新
  • 讀鎖&讀鎖->可重入
  • 讀鎖&寫鎖(寫鎖&讀鎖)->阻塞不可重入
public class ThreadDemo3 {
    //讀寫鎖
    static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();

    //讀鎖
    static  ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    //寫鎖
    static  ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
    //緩存
    static Map<String,Object> cache = new HashMap<String, Object>();

    /**
     * Description:根據key從緩存中獲取對象
     * @Param [key]
     * @return java.lang.Object
    **/

    public final Object getFromCache(String key){
        readLock.lock();//獲取'讀鎖'
        try {
            return cache.get(key);
        } finally {
            readLock.unlock();//釋放'讀鎖'
        }
    }

    /**
     * Description:向緩存中添加對象
     * @Param [key, value]
     * @return void
    **/

    public void putToCache(String key,final Object value){
        writeLock.lock();//獲取'寫鎖'
        try {
            cache.put(key,value);
        } finally {
            writeLock.unlock();//釋放'寫鎖'
        }
    }
}

5 AQS原理分析

  • 同步工具
    ReentrantLock 中AQS實現原理

ReentrantLock.Sync(內部類).lock()
Sync有兩個子類
FairSync-公平鎖(不允許插隊)
NonfairSync-非公平鎖(允許插隊)
分別重寫了lock()方法

6 AQS源碼分析

6.1 ReentrantLock 獲取鎖LOCK.lock();//獲得重入鎖時序圖

image.png

6.1 ReentrantLock 獲取鎖LOCK.lock();//獲得重入鎖流程圖

image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容