Java使用StampedLock實(shí)現(xiàn)高效讀寫功能
使用 StampedLock實(shí)現(xiàn)高效讀寫
1. 它是什么?
StampedLock
是 Java 8 引入的高性能鎖,提供了三種鎖模式:寫鎖、悲觀讀鎖和樂觀讀鎖。
與傳統(tǒng)的 ReentrantReadWriteLock
相比,StampedLock
更注重性能,特別適合讀多寫少的場(chǎng)景。
- 寫鎖:阻塞所有其他操作(類似獨(dú)占鎖)。
- 悲觀讀鎖:共享鎖,允許多個(gè)線程讀取,但會(huì)阻塞寫操作。
- 樂觀讀鎖:一種非阻塞讀操作,允許并發(fā)寫操作,并在必要時(shí)驗(yàn)證數(shù)據(jù)一致性。
2. 它的使用場(chǎng)景是什么?
- 讀多寫少的場(chǎng)景:如緩存、配置數(shù)據(jù)讀取等場(chǎng)景,
StampedLock
的樂觀讀鎖可以顯著提高性能。 - 需要快速讀鎖驗(yàn)證的場(chǎng)景:在樂觀讀的情況下,可以驗(yàn)證數(shù)據(jù)的一致性并在必要時(shí)降級(jí)為悲觀讀鎖。
- 寫鎖需要優(yōu)先處理的場(chǎng)景:避免傳統(tǒng)讀寫鎖中寫線程因讀操作而長(zhǎng)期饑餓的問題。
3. 它有哪些 API?
核心 API
方法名稱 | 描述 |
---|---|
writeLock() | 獲取寫鎖,返回一個(gè) stamp(鎖標(biāo)識(shí))。 |
readLock() | 獲取悲觀讀鎖,返回一個(gè) stamp(鎖標(biāo)識(shí))。 |
tryOptimisticRead() | 獲取樂觀讀鎖,返回一個(gè) stamp,非阻塞,適合快速讀取。 |
unlockWrite(long stamp) | 釋放寫鎖,需要傳入獲取鎖時(shí)返回的 stamp。 |
unlockRead(long stamp) | 釋放悲觀讀鎖,需要傳入獲取鎖時(shí)返回的 stamp。 |
validate(long stamp) | 驗(yàn)證樂觀讀鎖期間是否有寫操作發(fā)生,返回 true 表示數(shù)據(jù)未被修改。false 表示數(shù)據(jù)已經(jīng)被修改過 |
擴(kuò)展 API
方法名稱 | 描述 |
---|---|
tryWriteLock() | 嘗試獲取寫鎖,如果未成功立即返回。 |
tryReadLock() | 嘗試獲取讀鎖,如果未成功立即返回。 |
tryConvertToWriteLock(long stamp) | 嘗試將當(dāng)前鎖轉(zhuǎn)換為寫鎖,成功時(shí)返回新 stamp,否則返回 0。 |
tryConvertToReadLock(long stamp) | 嘗試將當(dāng)前鎖轉(zhuǎn)換為讀鎖,成功時(shí)返回新 stamp,否則返回 0。 |
isWriteLocked() | 檢查當(dāng)前鎖是否有寫鎖被占用。 |
isReadLocked() | 檢查當(dāng)前鎖是否有讀鎖被占用。 |
4. 它的使用方式
(1)寫鎖的使用
public void updateValue(double deltaX, double deltaY) { long stamp = lock.writeLock(); // 獲取寫鎖 try { x += deltaX; y += deltaY; } finally { lock.unlockWrite(stamp); // 釋放寫鎖 } }
(2)悲觀讀鎖的使用
public double readValue() { long stamp = lock.readLock(); // 獲取讀鎖 try { return Math.sqrt(x * x + y * y); } finally { lock.unlockRead(stamp); // 釋放讀鎖 } }
(3)樂觀讀鎖的使用
public double readValueOptimistically() { long stamp = lock.tryOptimisticRead(); // 獲取樂觀讀鎖 double currentX = x, currentY = y; if (!lock.validate(stamp)) { // 驗(yàn)證數(shù)據(jù)是否一致 stamp = lock.readLock(); // 如果不一致,降級(jí)為悲觀讀鎖 try { currentX = x; currentY = y; } finally { lock.unlockRead(stamp); // 釋放悲觀讀鎖 } } return Math.sqrt(currentX * currentX + currentY * currentY); }
(4)鎖升級(jí)的使用
public void conditionalUpdate(double deltaX, double deltaY) { long stamp = lock.readLock(); // 獲取悲觀讀鎖 try { if (x == 0 && y == 0) { // 檢查條件 stamp = lock.tryConvertToWriteLock(stamp); // 升級(jí)為寫鎖 if (stamp == 0L) { // 如果升級(jí)失敗 stamp = lock.writeLock(); // 顯式獲取寫鎖 } x += deltaX; y += deltaY; } } finally { lock.unlock(stamp); // 釋放鎖 } }
5. 它有哪些注意事項(xiàng)
(1)StampedLock 不可重入 StampedLock 不支持重入。如果同一線程嘗試再次獲取鎖(無(wú)論讀鎖還是寫鎖),會(huì)導(dǎo)致死鎖。
(2)鎖釋放需要傳入正確的 stamp 每次加鎖時(shí)都會(huì)返回一個(gè)唯一的 stamp,在釋放鎖時(shí)需要傳入對(duì)應(yīng)的 stamp,否則會(huì)拋出 IllegalMonitorStateException。
(3)寫優(yōu)先策略 StampedLock 優(yōu)先滿足寫鎖請(qǐng)求,避免了讀寫鎖可能出現(xiàn)的寫線程饑餓問題。
(4)線程安全 StampedLock 是線程安全的,但不支持條件變量(Condition),因此無(wú)法直接使用 wait 或 notify。
(5)適用場(chǎng)景 適合 讀多寫少 的場(chǎng)景。 不適合寫頻繁的場(chǎng)景,因?yàn)閷戞i的爭(zhēng)用會(huì)導(dǎo)致性能下降。
總結(jié)
StampedLock 是 Java 并發(fā)工具庫(kù)中的一顆“冷門寶石”,它通過樂觀讀鎖提供了高效的非阻塞讀機(jī)制,同時(shí)避免了寫線程饑餓的問題。熟悉其 API 和使用場(chǎng)景,能夠幫助你在性能敏感的場(chǎng)景中實(shí)現(xiàn)更高效的并發(fā)控制!
以上就是Java使用StampedLock實(shí)現(xiàn)高效讀寫功能的詳細(xì)內(nèi)容,更多關(guān)于Java StampedLock高效讀寫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot+Spring?Data?JPA整合H2數(shù)據(jù)庫(kù)的示例代碼
H2數(shù)據(jù)庫(kù)是一個(gè)開源的關(guān)系型數(shù)據(jù)庫(kù),本文重點(diǎn)給大家介紹SpringBoot+Spring?Data?JPA整合H2數(shù)據(jù)庫(kù)的示例代碼,感興趣的朋友跟隨小編一起看看吧2022-02-025個(gè)JAVA入門必看的經(jīng)典實(shí)例
這篇文章主要為大家詳細(xì)介紹了5個(gè)JAVA入門必看的經(jīng)典實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Java實(shí)戰(zhàn)之實(shí)現(xiàn)用戶登錄
這篇文章主要介紹了Java實(shí)戰(zhàn)之實(shí)現(xiàn)用戶登錄,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04java實(shí)現(xiàn)浮點(diǎn)數(shù)轉(zhuǎn)人民幣的小例子
java實(shí)現(xiàn)浮點(diǎn)數(shù)轉(zhuǎn)人民幣的小例子,需要的朋友可以參考一下2013-03-03SpringBoot項(xiàng)目動(dòng)態(tài)指定配置文件的方法示例
SpringBoot 作為 Java 開發(fā)中一個(gè)非常流行的框架,以其簡(jiǎn)化配置和快速啟動(dòng)應(yīng)用而聞名,在開發(fā)過程中,我們經(jīng)常需要根據(jù)不同的環(huán)境來加載不同的配置文件,本文給大家介紹了SpringBoot項(xiàng)目動(dòng)態(tài)指定配置文件的方法示例,需要的朋友可以參考下2024-12-12java HttpClient傳輸json格式的參數(shù)實(shí)例講解
這篇文章主要介紹了java HttpClient傳輸json格式的參數(shù)實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-01-01