[Java多線程 八]---JUC包下的鎖和工具類

原文鏈接 http://www.cnblogs.com/skywang12345/p/3496098.html

概述

根據鎖的添加到Java中的時間,Java中的鎖,可以分爲“同步鎖”“JUC包中的鎖”

同步鎖

實現方式

即通過synchronized關鍵字來進行同步,實現對競爭資源的互斥訪問的鎖。Java 1.0版本中就已經支持同步鎖了。

原理

同步鎖的原理是,對於每一個對象,有且僅有一個同步鎖;不同的線程能共同訪問該同步鎖。但是,在同一個時間點,該同步鎖能且只能被一個線程獲取到。這樣,獲取到同步鎖的線程就能進行CPU調度,從而在CPU上執行;而沒有獲取到同步鎖的線程,必須進行等待,直到獲取到同步鎖之後才能繼續運行。這就是,多線程通過同步鎖進行同步的原理!

JUC包中的鎖

這裏寫圖片描述

實現方式

相比同步鎖,JUC包中的鎖的功能更加強大,它爲鎖提供了一個框架,該框架允許更靈活地使用鎖,只是它的用法更難罷了。

內容

JUC包中的鎖,包括:

接口

Lock接口ReadWriteLock接口Condition條件接口

抽象類

AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer三個抽象類

普通類

ReentrantLock獨佔鎖(可重入同步鎖)ReentrantReadWriteLock讀寫鎖LockSupport阻塞原語

由於java.util.concurrent包下的三組信號量工具類CountDownLatchCyclicBarrierSemaphore也是通過AQS來實現的;因此,我也將它們歸納到鎖的框架中進行介紹。

鎖框架

這裏寫圖片描述

TML

JUC包下鎖詳述

用到的接口、抽象類和普通類

Lock接口

JUC包中的 Lock 接口支持那些語義不同(重入、公平等)的鎖規則。所謂語義不同,是指鎖可是有“公平機制的鎖”、”非公平機制的鎖”、”可重入的鎖”等等。

  • “公平機制”是指”不同線程獲取鎖的機制是公平的”,而”非公平機制”則是指”不同線程獲取鎖的機制是非公平的”,這裏的公平指的是如果公平,那麼等待鎖的多個線程將會按照申請鎖的時間順序來依次獲得鎖

  • “可重入的鎖”是指同一個鎖能夠被一個線程多次獲取

ReadWriteLock接口

ReadWriteLock 接口以和Lock類似的方式定義了一些讀取者可以共享而寫入者獨佔的鎖。JUC包只有一個類實現了該接口,即 ReentrantReadWriteLock,因爲它適用於大部分的標準用法上下文。但程序員可以創建自己的、適用於非標準要求的實現。

Condition接口

Condition需要和Lock聯合使用,它的作用是代替Object監視器方法,可以通過await(),signal()來休眠/喚醒線程。Condition 接口描述了可能會與鎖有關聯的條件變量。這些變量在用法上與使用 Object.wait 訪問的隱式監視器類似,但提供了更強大的功能。需要特別指出的是,單個 Lock 可能與多個 Condition 對象關聯。爲了避免兼容性問題,Condition 方法的名稱與對應的 Object 版本中的不同。

AQS抽象類

AbstractQueuedSynchronizer就是被稱之爲AQS的類,它是一個非常有用的超類,可用來定義鎖以及依賴於排隊阻塞線程的其他同步器

ReentrantLock,ReentrantReadWriteLock,CountDownLatch,CyclicBarrier和Semaphore等這些類都是基於AQS類實現的。AbstractQueuedLongSynchronizer 類提供相同的功能但擴展了對同步狀態的 64 位的支持。兩者都擴展了類 AbstractOwnableSynchronizer(一個幫助記錄當前保持獨佔同步的線程的簡單類)

LockSupport類

LockSupport的功能和”Thread中的Thread.suspend()和Thread.resume()有點類似”,LockSupport中的park() 和 unpark() 的作用分別是阻塞線程和解除阻塞線程但是park()和unpark()不會遇到“Thread.suspend 和 Thread.resume所可能引發的死鎖”問題

具體的實現類

ReentrantLock類

ReentrantLock是獨佔鎖。所謂獨佔鎖,是指只能被獨自佔領,即同一個時間點只能被一個線程鎖獲取到的鎖互斥同步語義)。ReentrantLock鎖包括”公平的ReentrantLock”和”非公平的ReentrantLock”(公平非公平語義)。”公平的ReentrantLock”是指”不同線程獲取鎖的機制是公平的”,而”非公平的  ReentrantLock”則是指”不同線程獲取鎖的機制是非公平的”,ReentrantLock是”可重入的鎖”(可重入語義)。

這裏寫圖片描述

  • ReentrantLock實現了Lock接口。

  • ReentrantLock中有一個成員變量sync,sync是Sync類型;Sync是一個抽象類,而且它繼承於AQS。

  • ReentrantLock中有”公平鎖類”FairSync和”非公平鎖類”NonfairSync,它們都是Sync的子類。ReentrantReadWriteLock中sync對象,是FairSync與NonfairSync中的一種,這也意味着ReentrantLock是”公平鎖”或”非公平鎖”中的一種,ReentrantLock默認是非公平鎖。

ReentrantReadWriteLock類

ReentrantReadWriteLock是讀寫鎖接口ReadWriteLock的實現類,它包括子類ReadLock和WriteLock。ReadLock是共享鎖,而WriteLock是獨佔鎖。

這裏寫圖片描述

  • ReentrantReadWriteLock實現了ReadWriteLock接口。

  • ReentrantReadWriteLock中包含sync對象,讀鎖readerLock和寫鎖writerLock讀鎖ReadLock和寫鎖WriteLock都實現了Lock接口

  • 和”ReentrantLock”一樣,sync是Sync類型;而且,Sync也是一個繼承於AQS的抽象類。Sync也包括”公平鎖”FairSync和”非公平鎖”NonfairSync

輔助工具類

CountDownLatch類

CountDownLatch是一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。CountDownLatch的UML類圖如下:

這裏寫圖片描述

CyclicBarrier類

CyclicBarrier[ˈsaɪklɪk][ˈbæriə(r)]是一個同步輔助類,允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。因爲該 barrier 在釋放等待線程後可以重用,所以稱它爲循環 的 barrier。

這裏寫圖片描述

CyclicBarrier是包含了“ReentrantLock對象lock”和”Condition對象trip”,它是通過獨佔鎖實現的。

CyclicBarrier和CountDownLatch的區別是:

  (01)* CountDownLatch的作用是允許1或N個線程等待其他線程完成執行;而CyclicBarrier則是允許N個線程相互等待。*
  
  (02) CountDownLatch的計數器無法被重置;CyclicBarrier的計數器可以被重置後使用,因此它被稱爲是循環的barrier。

Semaphore

Semaphore[ˈseməfɔ:(r)]是一個計數信號量,它的本質是一個“共享鎖“。信號量維護了一個信號量許可集。線程可以通過調用acquire()來獲取信號量的許可;當信號量中有可用的許可時,線程能獲取該許可;否則線程必須等待,直到有可用的許可爲止。 線程可以通過release()來釋放它所持有的信號量許可。

這裏寫圖片描述

和”ReentrantLock”一樣,Semaphore包含了sync對象,sync是Sync類型;而且,Sync也是一個繼承於AQS的抽象類。Sync也包括”公平信號量”FairSync和”非公平信號量”NonfairSync。

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