天天看點

阿裡二面:ReentrantLook公平鎖和非公平鎖底層分别是如何實作的?

作者:JAVA面試官

ReentrantLook公平鎖和非公平鎖底層分别是如何實作的?

公平鎖和非公平鎖主要展現在加鎖的時候,公平鎖在加鎖的時候,一個線程要來加鎖了,它會先去檢查隊列裡面是不是有線程在排隊,如果有線程排隊,那麼它老老實實地排隊,這就是公平鎖。

阿裡二面:ReentrantLook公平鎖和非公平鎖底層分别是如何實作的?

什麼是非公平鎖呢?就是說當一個線程要來加鎖的時候,它不會去排隊,而是直接去競争這把鎖。除非它沒有競争到,它再來排隊,是以這是非公平的。

阿裡二面:ReentrantLook公平鎖和非公平鎖底層分别是如何實作的?

這兩個差別就是說一開始的時候,它會不會去排隊。公平的會先去排隊。不公平的會先去競争,先去看能不能拿到這把鎖,如果不能拿到,它才會來排隊。

不管是公平鎖還是非公平鎖,一旦沒有競争到鎖,競争失敗了都會排隊。但是釋放鎖的時候,兩者都是喚醒排在最前面的線程。公平和非公平隻展現在加鎖的階段,并不展現在喚醒鎖的階段。

FairSync、NonfairSync 代表公平鎖和非公平鎖。兩者都是 ReentrantLock 靜态内部類,隻不過實作不同鎖語義。兩者的都繼承自 ReentrantLock 靜态抽象内部類 Sync,Sync 類繼承自 AQS,這裡就有個疑問,這些鎖都沒有直接繼承 AQS,而是定義了一個 Sync 類去繼承 AQS,為什麼要這樣呢?因為 鎖面向的是使用使用者,同步器面向的則是線程控制,那麼在鎖的實作中聚合同步器而不是直接繼承 AQS 就可以很好的隔離二者所關注的事情。

阿裡二面:ReentrantLook公平鎖和非公平鎖底層分别是如何實作的?

AQS 的全稱為 AbstractQueuedSynchronizer ,翻譯過來的意思就是抽象隊列同步器。這個類在 java.util.concurrent.locks 包下面。Java中的大部分同步類(Lock、Semaphore、ReentrantLock等)都是基于AbstractQueuedSynchronizer(簡稱為AQS)實作的。AQS是一種提供了原子式管理同步狀态、阻塞和喚醒線程功能以及隊列模型的簡單架構。

阿裡二面:ReentrantLook公平鎖和非公平鎖底層分别是如何實作的?
阿裡二面:ReentrantLook公平鎖和非公平鎖底層分别是如何實作的?

ReentrantLock還是可重入鎖,就是不管是公平還是非公平的,其實都是可重入的。可重入的意思就是一個線程,現在加到這把鎖了,那麼假設我的代碼層面,後續又來加這把鎖,那麼其實可以直接加的。就同一個線程可以連續的去加同一把鎖。

繼續閱讀