国产精品免费嫩草研究院|无遮羞动漫在线观看AV|国产麻豆精品传媒AV国产在线|村在线观看|寂寞情人1正版|韩国床震韩国床震古|精品系列专区久久

Java 讀寫鎖 ReadWriteLock 原理與應用場景詳解


Java 讀寫鎖 ReadWriteLock 原理與應用場景詳解

文章插圖
Java并發編程提供了讀寫鎖,主要用于讀多寫少的場景,今天我就重點來講解讀寫鎖的底層實現原理@mikechen
什么是讀寫鎖?讀寫鎖并不是JAVA所特有的讀寫鎖(Readers-Writer Lock)顧名思義是一把鎖分為兩部分:讀鎖和寫鎖,其中讀鎖允許多個線程同時獲得,因為讀操作本身是線程安全的,而寫鎖則是互斥鎖,不允許多個線程同時獲得寫鎖,并且寫操作和讀操作也是互斥的 。
所謂的讀寫鎖(Readers-Writer Lock),顧名思義就是將一個鎖拆分為讀鎖和寫鎖兩個鎖 。
其中讀鎖允許多個線程同時獲得,而寫鎖則是互斥鎖,不允許多個線程同時獲得寫鎖,并且寫操作和讀操作也是互斥的 。
Java 讀寫鎖 ReadWriteLock 原理與應用場景詳解

文章插圖
為什么需要讀寫鎖?Synchronized 和 ReentrantLock 都是獨占鎖,即在同一時刻只有一個線程獲取到鎖 。
然而在有些業務場景中,我們大多在讀取數據,很少寫入數據,這種情況下,如果仍使用獨占鎖,效率將及其低下 。
針對這種情況,Java提供了讀寫鎖——ReentrantReadWriteLock 。
主要解決:對共享資源有讀和寫的操作,且寫操作沒有讀操作那么頻繁的場景 。
讀寫鎖的特點
  • 公平性:讀寫鎖支持非公平和公平的鎖獲取方式,非公平鎖的吞吐量優于公平鎖的吞吐量,默認構造的是非公平鎖
  • 可重入:在線程獲取讀鎖之后能夠再次獲取讀鎖,但是不能獲取寫鎖,而線程在獲取寫鎖之后能夠再次獲取寫鎖,同時也能獲取讀鎖
  • 鎖降級:線程獲取寫鎖之后獲取讀鎖,再釋放寫鎖,這樣實現了寫鎖變為讀鎖,也叫鎖降級
讀寫鎖的使用場景ReentrantReadWriteLock適合讀多寫少的場景:
讀鎖ReentrantReadWriteLock.ReadLock可以被多個線程同時持有, 所以并發能力很高 。
寫鎖ReentrantReadWriteLock.WriteLock是獨占鎖, 在一個線程持有寫鎖時候, 其他線程都不能在搶占, 包含搶占讀鎖都會阻塞 。
ReentrantReadWriteLock的使用場景總結:其實就是 讀讀并發、讀寫互斥、寫寫互斥而已,如果一個對象并發讀的場景大于并發寫的場景,那就可以使用 ReentrantReadWriteLock來達到保證線程安全的前提下提高并發效率 。
讀寫鎖的主要成員和結構圖1. ReentrantReadWriteLock的繼承關系
Java 讀寫鎖 ReadWriteLock 原理與應用場景詳解

文章插圖
public interface ReadWriteLock {/*** Returns the lock used for reading.** @return the lock used for reading.*/Lock readLock();/*** Returns the lock used for writing.** @return the lock used for writing.*/Lock writeLock();}讀寫鎖 ReadWriteLock
讀寫鎖維護了一對相關的鎖,一個用于只讀操作,一個用于寫入操作 。
只要沒有寫入,讀取鎖可以由多個讀線程同時保持,寫入鎖是獨占的 。
2.ReentrantReadWriteLock的核心變量
Java 讀寫鎖 ReadWriteLock 原理與應用場景詳解

文章插圖
ReentrantReadWriteLock類包含三個核心變量:
  1. ReaderLock:讀鎖,實現了Lock接口
  2. WriterLock:寫鎖,也實現了Lock接口
  3. Sync:繼承自AbstractQueuedSynchronize(AQS),可以為公平鎖FairSync 或 非公平鎖NonfairSync
3.ReentrantReadWriteLock的成員變量和構造函數
/** 內部提供的讀鎖 */private final ReentrantReadWriteLock.ReadLock readerLock;/** 內部提供的寫鎖 */private final ReentrantReadWriteLock.WriteLock writerLock;/** AQS來實現的同步器 */final Sync sync;/*** Creates a new {@code ReentrantReadWriteLock} with* 默認創建非公平的讀寫鎖*/public ReentrantReadWriteLock() {this(false);}/*** Creates a new {@code ReentrantReadWriteLock} with* the given fairness policy.** @param fair {@code true} if this lock should use a fair ordering policy*/public ReentrantReadWriteLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();readerLock = new ReadLock(this);writerLock = new WriteLock(this);}

經驗總結擴展閱讀