java多線程(四)

java八種類型:公平鎖/非公平鎖、可重入鎖、獨享鎖/共享鎖、互斥鎖/讀寫鎖、樂觀鎖/悲觀鎖、分段鎖、偏向鎖/輕量級鎖/重量級鎖、自旋鎖。java

1、公平鎖/非公平鎖:併發

公平鎖是指多個線程按照申請鎖的順序來獲取鎖。
非公平鎖是指多個線程獲取鎖的順序並非按照申請鎖的順序,有可能後申請的線程比先申請的線程優先獲取鎖。有可能,會形成優先級反轉或者飢餓現象。
對於Java ReentrantLock而言,經過構造函數指定該鎖是不是公平鎖,默認是非公平鎖。非公平鎖的優勢在於吞吐量比公平鎖大。
對於synchronized而言,也是一種非公平鎖。因爲其並不像ReentrantLock是經過AQS的來實現線程調度,因此並無任何辦法使其變成公平鎖。
2、可重入鎖:函數

可重入鎖又名遞歸鎖,是指在同一個線程在外層方法獲取鎖的時候,在進入內層方法會自動獲取鎖。對於Java ReentrantLock而言, 其名字是Re entrant Lock便是從新進入鎖。對於synchronized而言,也是一個可重入鎖。可重入鎖的一個好處是可必定程度避免死鎖。性能

synchronized void setA() throws Exception{
Thread.sleep(1000);
setB();
}atom

synchronized void setB() throws Exception{
Thread.sleep(1000);
}
上面的代碼就是一個可重入鎖的一個特色,若是不是可重入鎖的話,setB可能不會被當前線程執行,可能形成死鎖。

線程

3、獨享鎖/共享鎖:對象

獨享鎖是指該鎖一次只能被一個線程所持有;共享鎖是指該鎖可被多個線程所持有。遞歸

對於Java ReentrantLock而言,其是獨享鎖。可是對於Lock的另外一個實現類ReadWriteLock,其讀鎖是共享鎖,其寫鎖是獨享鎖。讀鎖的共享鎖可保證併發讀是很是高效的,讀寫、寫讀 、寫寫的過程是互斥的。獨享鎖與共享鎖也是經過AQS來實現的,經過實現不一樣的方法,來實現獨享或者共享。對於synchronized而言,固然是獨享鎖。同步

4、互斥鎖/讀寫鎖:it

上面說到的獨享鎖/共享鎖就是一種廣義的說法,互斥鎖/讀寫鎖就是具體的實現。互斥鎖在Java中的具體實現就是ReentrantLock;讀寫鎖在Java中的具體實現就是ReadWriteLock。

5、樂觀鎖/悲觀鎖:

樂觀鎖與悲觀鎖不是指具體的什麼類型的鎖,而是指看待併發同步的角度。

悲觀鎖:老是假設最壞的狀況,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖。好比Java裏面的同步原語synchronized關鍵字的實現就是悲觀鎖。

樂觀鎖:顧名思義,就是很樂觀,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量,在Java中java.util.concurrent.atomic包下面的原子變量類就是使用了樂觀鎖的一種實現方式CAS(Compare and Swap 比較並交換)實現的。
6、分段鎖:看HashMap

7、偏向鎖/輕量級鎖/重量級鎖

這三種鎖是指鎖的狀態,而且是針對synchronized。在Java 5經過引入鎖升級的機制來實現高效synchronized。這三種鎖的狀態是經過對象監視器在對象頭中的字段來代表的。

偏向鎖是指一段同步代碼一直被一個線程所訪問,那麼該線程會自動獲取鎖。下降獲取鎖的代價。

輕量級鎖是指當鎖是偏向鎖的時候,被另外一個線程所訪問,偏向鎖就會升級爲輕量級鎖,其餘線程會經過自旋的形式嘗試獲取鎖,不會阻塞,提升性能。

重量級鎖是指當鎖爲輕量級鎖的時候,另外一個線程雖然是自旋,但自旋不會一直持續下去,當自旋必定次數的時候,尚未獲取到鎖,就會進入阻塞,該鎖膨脹爲重量級鎖。重量級鎖會讓其餘申請的線程進入阻塞,性能下降。
8、自旋鎖:在Java中,自旋鎖是指嘗試獲取鎖的線程不會當即阻塞,而是採用循環的方式去嘗試獲取鎖,這樣的好處是減小線程上下文切換的消耗,缺點是循環會消耗CPU。

相關文章
相關標籤/搜索