搜尋
首頁Javajava教程解讀Java8新特性--StampedLock

解讀Java8新特性--StampedLock

Jun 17, 2017 pm 02:15 PM
java8特性解讀

本文從synchronized、Lock到Java8新增的StampedLock進行比較分析,對Java8新特性之StampedLock相關知識感興趣的朋友一起看看吧

Java8就像一個寶藏,一個小的API改進,也足與寫一篇文章,例如同步,一直是多線程並發編程的一個老話題,相信沒有人喜歡同步的代碼,這會降低應用的吞吐量等性能指標,最壞的時候會掛起死機,但是即使這樣你也沒得選擇,因為要確保資訊的正確性。所以這篇文章決定將從synchronized、Lock到Java8新增的StampedLock進行比較分析,相信StampedLock不會讓大家失望。

synchronized

在java5之前,實作同步主要是使用synchronized。它是Java語言的關鍵字,當它用來修飾一個方法或一個程式碼區塊的時候,能夠保證在同一時刻最多只有一個執行緒執行該段程式碼。

有四個不同的同步區塊:

1.實例方法

2.靜態方法

3.實例方法中的同步區塊

4.靜態方法中的同步區塊

大家對此應該不陌生,所以不多講了,以下是程式碼範例


synchronized(this)
// do operation
}

小結:在多線程並發編程中Synchronized一直是元老級角色,很多人都會稱呼它為重量級鎖,但是隨著Java SE1.6對Synchronized進行了各種優化之後,性能上也有所提升。

Lock

它是Java 5在java.util.concurrent.locks新增的一個API。

Lock是一個接口,核心方法是lock(),unlock(),tryLock(),實作類別有ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock;

ReentrantReadWriteLock,ReadWriteLock, ReentrantLock 和synchronized鎖都有相同的記憶體語意。

與synchronized不同的是,Lock完全用Java寫成,在java這個層面是無關JVM實現的。 Lock提供更靈活的鎖機制,很多synchronized 沒有提供的許多特性,例如鎖投票,定時鎖等候和中斷鎖等候,但因為lock是透過程式碼實現的,要保證鎖定一定會被釋放,就必須將unLock( )放到finally{}中

下面是Lock的一個程式碼範例


rwlock.writeLock().lock();
try {
// do operation
} finally {
rwlock.writeLock().unlock();
}

小結:比synchronized更靈活、更具可擴展性的鎖定機制,但不管怎麼說還是synchronized程式碼要更容易書寫些

#StampedLock

##它是java8在java.util.concurrent.locks新增的一個API。


ReentrantReadWriteLock 在沒有任何讀寫鎖時,才可以取得寫入鎖,這可用於實現了悲觀讀取(Pessimistic Reading),即如果執行中進行讀取時,經常可能有另一個執行要寫入的需求,為了保持同步,ReentrantReadWriteLock 的讀取鎖定就可派上用場。


然而,如果讀取執行情況很多,寫入很少的情況下,使用ReentrantReadWriteLock 可能會使寫入執行緒遭遇飢餓(Starvation)問題,也就是寫入執行緒吃吃無法競爭到鎖定而一直處於等待狀態。

StampedLock控制鎖有三種模式(寫,讀,樂觀讀),一個StampedLock狀態是由版本和模式兩個部分組成,鎖獲取方法返回一個數字作為票據stamp,它用相應的鎖狀態表示並控制訪問,數字0表示沒有寫鎖被授權訪問。在讀鎖上分為悲觀鎖和樂觀鎖。


所謂的樂觀讀模式,也就是若讀的操作很多,寫的操作很少的情況下,你可以樂觀地認為,寫入與讀取同時發生幾率很少,因此不悲觀地使用完全的讀取鎖定,程式可以查看讀取資料之後,是否遭到寫入執行的變更,再採取後續的措施(重新讀取變更信息,或者

拋出異常) ,這一個小小改進,可大幅度提高程式的吞吐量! !

下面是java doc提供的StampedLock一個例子


#

class Point {
 private double x, y;
 private final StampedLock sl = new StampedLock();
 void move(double deltaX, double deltaY) { // an exclusively locked method
  long stamp = sl.writeLock();
  try {
  x += deltaX;
  y += deltaY;
  } finally {
  sl.unlockWrite(stamp);
  }
 }
 //下面看看乐观读锁案例
 double distanceFromOrigin() { // A read-only method
  long stamp = sl.tryOptimisticRead(); //获得一个乐观读锁
  double currentX = x, currentY = y; //将两个字段读入本地局部变量
  if (!sl.validate(stamp)) { //检查发出乐观读锁后同时是否有其他写锁发生?
  stamp = sl.readLock(); //如果没有,我们再次获得一个读悲观锁
  try {
   currentX = x; // 将两个字段读入本地局部变量
   currentY = y; // 将两个字段读入本地局部变量
  } finally {
   sl.unlockRead(stamp);
  }
  }
  return Math.sqrt(currentX * currentX + currentY * currentY);
 }
//下面是悲观读锁案例
 void moveIfAtOrigin(double newX, double newY) { // upgrade
  // Could instead start with optimistic, not read mode
  long stamp = sl.readLock();
  try {
  while (x == 0.0 && y == 0.0) { //循环,检查当前状态是否符合
   long ws = sl.tryConvertToWriteLock(stamp); //将读锁转为写锁
   if (ws != 0L) { //这是确认转为写锁是否成功
   stamp = ws; //如果成功 替换票据
   x = newX; //进行状态改变
   y = newY; //进行状态改变
   break;
   }
   else { //如果不能成功转换为写锁
   sl.unlockRead(stamp); //我们显式释放读锁
   stamp = sl.writeLock(); //显式直接进行写锁 然后再通过循环再试
   }
  }
  } finally {
  sl.unlock(stamp); //释放读锁或写锁
  }
 }
 }

小結:

StampedLock要比ReentrantReadWriteLock更廉價,也就是消耗比較小。

StampedLock與ReadWriteLock效能比較

下圖是和ReadWritLock相比,在一個執行緒情況下,是讀速度其4倍左右,寫是1倍。

下圖是六個執行緒情況下,讀取效能是其數十倍,寫入效能也是近10倍左右:

下圖是吞吐量提高:

總結

#1、synchronized是在JVM層面上實現的,不但可以透過一些監控工具監控synchronized的鎖定,而且在程式碼執行時出現異常,JVM會自動釋放鎖定;

2、ReentrantLock、ReentrantReadWriteLock,、StampedLock都是物件層面的鎖定,要保證鎖定一定會被釋放,就必須將unLock()放到finally{}中;

3、StampedLock 對吞吐量有巨大的改進,特別是在讀取線程越來越多的場景下;

# 4.StampedLock有一個複雜的API,對於加鎖操作,很容易誤用其他方法;

#5、當只有少量競爭者的時候,synchronized是一個很好的通用的鎖定實現;

6、當執行緒成長能夠預估,ReentrantLock是一個很好的通用的鎖定實作;

以上是解讀Java8新特性--StampedLock的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
是否有任何威脅或增強Java平台獨立性的新興技術?是否有任何威脅或增強Java平台獨立性的新興技術?Apr 24, 2025 am 12:11 AM

新興技術對Java的平台獨立性既有威脅也有增強。 1)雲計算和容器化技術如Docker增強了Java的平台獨立性,但需要優化以適應不同雲環境。 2)WebAssembly通過GraalVM編譯Java代碼,擴展了其平台獨立性,但需與其他語言競爭性能。

JVM的實現是什麼,它們都提供了相同的平台獨立性?JVM的實現是什麼,它們都提供了相同的平台獨立性?Apr 24, 2025 am 12:10 AM

不同JVM實現都能提供平台獨立性,但表現略有不同。 1.OracleHotSpot和OpenJDKJVM在平台獨立性上表現相似,但OpenJDK可能需額外配置。 2.IBMJ9JVM在特定操作系統上表現優化。 3.GraalVM支持多語言,需額外配置。 4.AzulZingJVM需特定平台調整。

平台獨立性如何降低發展成本和時間?平台獨立性如何降低發展成本和時間?Apr 24, 2025 am 12:08 AM

平台獨立性通過在多種操作系統上運行同一套代碼,降低開發成本和縮短開發時間。具體表現為:1.減少開發時間,只需維護一套代碼;2.降低維護成本,統一測試流程;3.快速迭代和團隊協作,簡化部署過程。

Java的平台獨立性如何促進代碼重用?Java的平台獨立性如何促進代碼重用?Apr 24, 2025 am 12:05 AM

Java'splatformindependencefacilitatescodereusebyallowingbytecodetorunonanyplatformwithaJVM.1)Developerscanwritecodeonceforconsistentbehavioracrossplatforms.2)Maintenanceisreducedascodedoesn'tneedrewriting.3)Librariesandframeworkscanbesharedacrossproj

您如何在Java應用程序中對平台特定問題進行故障排除?您如何在Java應用程序中對平台特定問題進行故障排除?Apr 24, 2025 am 12:04 AM

要解決Java應用程序中的平台特定問題,可以採取以下步驟:1.使用Java的System類查看系統屬性以了解運行環境。 2.利用File類或java.nio.file包處理文件路徑。 3.根據操作系統條件加載本地庫。 4.使用VisualVM或JProfiler優化跨平台性能。 5.通過Docker容器化確保測試環境與生產環境一致。 6.利用GitHubActions在多個平台上進行自動化測試。這些方法有助於有效地解決Java應用程序中的平台特定問題。

JVM中的類加載程序子系統如何促進平台獨立性?JVM中的類加載程序子系統如何促進平台獨立性?Apr 23, 2025 am 12:14 AM

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器會產生特定於平台的代碼嗎?解釋。Java編譯器會產生特定於平台的代碼嗎?解釋。Apr 23, 2025 am 12:09 AM

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

JVM如何處理不同操作系統的多線程?JVM如何處理不同操作系統的多線程?Apr 23, 2025 am 12:07 AM

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),