日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程安全StampedLock

發布時間:2024/9/30 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程安全StampedLock 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/120854573
本文出自【趙彥軍的博客】

Java線程安全StampedLock
Java線程安全Lock、ReentrantLock、ReentrantReadWriteLock
Java線程安全集合總結
Java原子操作Atomic

文章目錄

  • ReadWriteLock
  • 小結

ReadWriteLock

前面介紹的ReadWriteLock可以解決多線程同時讀,但只有一個線程能寫的問題。

如果我們深入分析ReadWriteLock,會發現它有個潛在的問題:如果有線程正在讀,寫線程需要等待讀線程釋放鎖后才能獲取寫鎖,即讀的過程中不允許寫,這是一種悲觀的讀鎖。

要進一步提升并發執行效率,Java 8引入了新的讀寫鎖:StampedLock。

StampedLock和ReadWriteLock相比,改進之處在于:讀的過程中也允許獲取寫鎖后寫入!這樣一來,我們讀的數據就可能不一致,所以,需要一點額外的代碼來判斷讀的過程中是否有寫入,這種讀鎖是一種樂觀鎖。

樂觀鎖的意思就是樂觀地估計讀的過程中大概率不會有寫入,因此被稱為樂觀鎖。反過來,悲觀鎖則是讀的過程中拒絕有寫入,也就是寫入必須等待。顯然樂觀鎖的并發效率更高,但一旦有小概率的寫入導致讀取的數據不一致,需要能檢測出來,再讀一遍就行。

我們來看例子:

public class Point {private final StampedLock stampedLock = new StampedLock();private double x;private double y;public void move(double deltaX, double deltaY) {long stamp = stampedLock.writeLock(); // 獲取寫鎖try {x += deltaX;y += deltaY;} finally {stampedLock.unlockWrite(stamp); // 釋放寫鎖}}public double distanceFromOrigin() {long stamp = stampedLock.tryOptimisticRead(); // 獲得一個樂觀讀鎖// 注意下面兩行代碼不是原子操作// 假設x,y = (100,200)double currentX = x;// 此處已讀取到x=100,但x,y可能被寫線程修改為(300,400)double currentY = y;// 此處已讀取到y,如果沒有寫入,讀取是正確的(100,200)// 如果有寫入,讀取是錯誤的(100,400)if (!stampedLock.validate(stamp)) { // 檢查樂觀讀鎖后是否有其他寫鎖發生stamp = stampedLock.readLock(); // 獲取一個悲觀讀鎖try {currentX = x;currentY = y;} finally {stampedLock.unlockRead(stamp); // 釋放悲觀讀鎖}}return Math.sqrt(currentX * currentX + currentY * currentY);} }

和ReadWriteLock相比,寫入的加鎖是完全一樣的,不同的是讀取。注意到首先我們通過tryOptimisticRead()獲取一個樂觀讀鎖,并返回版本號。接著進行讀取,讀取完成后,我們通過validate()去驗證版本號,如果在讀取過程中沒有寫入,版本號不變,驗證成功,我們就可以放心地繼續后續操作。如果在讀取過程中有寫入,版本號會發生變化,驗證將失敗。在失敗的時候,我們再通過獲取悲觀讀鎖再次讀取。由于寫入的概率不高,程序在絕大部分情況下可以通過樂觀讀鎖獲取數據,極少數情況下使用悲觀讀鎖獲取數據。

可見,StampedLock把讀鎖細分為樂觀讀和悲觀讀,能進一步提升并發效率。但這也是有代價的:一是代碼更加復雜,二是StampedLock是不可重入鎖,不能在一個線程中反復獲取同一個鎖。

StampedLock還提供了更復雜的將悲觀讀鎖升級為寫鎖的功能,它主要使用在if-then-update的場景:即先讀,如果讀的數據滿足條件,就返回,如果讀的數據不滿足條件,再嘗試寫。

小結

StampedLock提供了樂觀讀鎖,可取代ReadWriteLock以進一步提升并發性能;

StampedLock是不可重入鎖。

總結

以上是生活随笔為你收集整理的Java线程安全StampedLock的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。