Java併發基礎(八)-locks包

1. 前言

Java鎖的種類 java中的鎖種類是真的多。而locks包下也有一些。包結構如下:
這裏寫圖片描述

  • AbstractOwnableSynchronizer 一個線程擁有的同步器,這個類提供了創建鎖和相關同步器的基礎
  • AbstractQueuedLongSynchronizer 所有的同步狀態都是用long變量來維護的,而不是int,在需要64位的屬性來表示狀態的時候會很有用
  • AbstractQueuedSynchronizer 爲實現依賴於先進先出隊列的阻塞鎖和相關同步器(信號量、事件等等)提供的一個框架,它依靠int值來表示狀態
  • Condition 將 Object 監視器方法(wait、notify 和 notifyAll)分解成截然不同的對象,以便通過將這些對象與任意 Lock 實現組合使用,爲每個對象提供多個等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和語句的使用。這個是被綁定在Lock上一起使用的。
  • Lock 實現了比synchronized更多的功能,需要注意的是,爲了確保可以釋放鎖,需要在finally語句塊中unlock。
  • LockSupport LockSupport是用來創建鎖和其他同步類的基本線程阻塞原語。LockSupport中的park() 和 unpark() 的作用分別是阻塞線程和解除阻塞線程,而且park()和unpark()不會遇到“Thread.suspend 和 Thread.resume所可能引發的死鎖”問題。
  • ReadWriteLock 讀寫鎖,讀和寫是互斥的,多個讀鎖不互斥,也就是說,在讀的時候,不能寫,在寫的時候,不能讀,但是在讀的時候可以有多個線程同時讀。
  • ReentrantLock 可重入鎖
  • ReentrantReadWriteLock 可重入讀寫鎖
  • StampedLock Java 1.8提供了一種讀寫鎖,

2. Condition

Condition是和Lock綁定使用的。Lock#newCondition方法返回一個Condition。
使用方法如下:

  • 創建Lock
  • Lock#newCondition 返回新的Condition (可以多次調用)
  • Condition#await 會導致線程掛起直到signalled,或者中斷。
  • Condition#signal 喚醒線程

ArrayBlockingQueue中有大量這樣的用法。如圖:
這裏寫圖片描述

3. LockSupport

  • park方法能將阻塞線程或者
  • unpark 方法喚醒線程

4. ReentrantReadWriteLock

ReentrantReadWriteLock是locks包中提供的讀寫鎖的一種實現,用法也很簡單。一般用jdk提供的ReentrantReadWriteLock。

用法如下

  • 初始化
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();
  • 在需要讀的時候readLock.lock(),用完之後readLock.unlock()
  • 在需要寫的時候writeLock.lock(),用完之後writeLock.unlock()

ReentrantReadWriteLock支持鎖降級

什麼是鎖降級呢。從讀寫角度來看,寫的級別是高於讀的。咱們看例子

    public static void main(String[] args){
        ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        final Lock readLock = readWriteLock.readLock();
        final Lock writeLock = readWriteLock.writeLock();
        // 讀
        readLock.lock();
        System.err.println("我是讀鎖");
        // 寫
        writeLock.lock();
        System.err.println("我是寫鎖");

    }

很明顯,由於不支持鎖升級,因此,會阻塞。輸出結果如下
這裏寫圖片描述

我們上面讀寫翻個順序。

        // 寫
        writeLock.lock();
        System.err.println("我是寫鎖");
        // 讀
        readLock.lock();
        System.err.println("我是讀鎖");

輸出結果如下:
這裏寫圖片描述

鎖降級,將寫入鎖降級爲讀鎖(很好理解,就像寫權限要高於讀權限一樣)

5. ReentrantLock

也叫做遞歸鎖,指的是同一線程 外層函數獲得鎖之後 ,內層遞歸函數仍然有獲取該鎖的代碼,但不受影響

這種鎖在ArrayBlockingQueue中有用到。
這裏寫圖片描述

關於用法這裏就不說了。
ReentrantLock可是實現公平鎖

    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

從構造函數中來看,是支持公平鎖的。

公平鎖,等待時間長的優先獲得鎖。

6. StampedLock

這裏想的半天,還是覺得參考資料裏面寫的很完美,所以,我就不獻醜了。大家去看看吧。


參考資料

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