JAVA多線程之鎖

1.樂觀鎖
    樂觀鎖是一種概念,它認爲程序讀多寫少。
    那麼在獲取數據的時候不加鎖,而在更新的時候判斷此期間這個值有沒有改變(讀版本號),如果沒變就加鎖更新,變化了就重新讀取。(CAS)
    
2.悲觀鎖
    悲觀鎖也是一種概念,它認爲程序寫多讀少。
    那麼不管在獲取數據的時候還是更新數據的時候都對操作進行加鎖。
    java中的悲觀鎖常見的就是關鍵詞Synchronized。
    AQS框架下的鎖則是先嚐試cas樂觀鎖去獲取鎖,獲取不到,纔會轉換爲悲觀鎖,如 RetreenLock
    
3.自旋鎖
    是一種非阻塞鎖,也就是說,如果某線程需要獲取鎖,但該鎖已經被其他線程佔用時,
    該線程不會被掛起,而是在不斷的消耗CPU的時間,不停的試圖獲取鎖,一旦鎖被釋放能立即獲得鎖(減少線程上下文切換,從用戶態到內核態)
    適用於對鎖競爭不激烈,且同步代碼執行時間快的程序。

4.同步鎖
    synchronized 它可以把任意一個非 null 的對象當作鎖。
    他屬於獨佔式的悲觀鎖,同時屬於可重入鎖。
    Synchronized 核心 組件
        1) Wait Set:哪些調用 wait 方法被阻塞的線程被放置在這裏;
        2) Contention List:競爭隊列,所有請求鎖的線程首先被放在這個競爭隊列中;
        3) Entry List:Contention List 中那些有資格成爲候選資源的線程被移動到 Entry List 中;
        4) OnDeck:任意時刻,最多隻有一個線程正在競爭鎖資源,該線程被成爲 OnDeck;
        5) Owner:當前已經獲取到所資源的線程被稱爲 Owner;
        6) !Owner:當前釋放鎖的線程。
        
5.ReentrantLock
    ReentantLock 繼承接口 Lock 並實現了接口中定義的方法,他是一種可重入鎖,除了能完
    成 synchronized 所能完成的所有工作外,還提供了諸如可響應中斷鎖、可輪詢鎖請求、定時鎖等避免多線程死鎖的方法。
    PS:ReentantLock和Synchronized相比是鎖可中斷,可加多個鎖,實現公平鎖。
    
6.Semaphore(信號量)
     Semaphore semaphore = new Semaphore(int permits , boolean isFair)
     在業務代碼使用時表示最多能有permits個線程同時處理,並且能實現是否爲公平鎖isFair
     
7.AtomicXXX(原子操作)
    提供對XXX對象的原子操作
    
8.可重入鎖(遞歸鎖)
    可重入鎖,也叫做遞歸鎖,指的是同一線程 外層函數獲得鎖之後 ,內層遞歸函數仍然有獲取該鎖的代碼,但不受影響。
    在 JAVA 環境下 ReentrantLock 和 synchronized 都是可重入鎖。
    
9.公平鎖與非公平鎖
    a.公平鎖:加鎖前檢查是否有排隊等待的線程,優先排隊等待的線程,先來先得(率先請求鎖資源的線程先獲取鎖)
    b.非公平鎖:加鎖時不考慮排隊等待問題,直接嘗試獲取鎖,獲取不到自動到隊尾等待
    
10.ReadWriteLock(讀寫鎖)
    a.Java併發庫中ReetrantReadWriteLock實現了ReadWriteLock接口並添加了可重入的特性
    b.ReetrantReadWriteLock讀寫鎖的效率明顯高於synchronized關鍵字
    c.ReetrantReadWriteLock讀寫鎖的實現中,讀鎖使用共享模式;寫鎖使用獨佔模式,
        換句話說,讀鎖可以在沒有寫鎖的時候被多個線程同時持有,寫鎖是獨佔的
    d.ReetrantReadWriteLock讀寫鎖的實現中,需要注意的,當有讀鎖時,寫鎖就不能獲得(鎖升級);
        而當有寫鎖時,除了獲得寫鎖的這個線程可以獲得讀鎖外(鎖降級),其他線程不能獲得讀鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章