首頁 > Java > java教程 > java中Lock API概述

java中Lock API概述

Linda Hamilton
發布: 2024-12-31 18:59:14
原創
484 人瀏覽過

Overview of Lock API in java

管理對共享資源的存取對於在並發程式設計中確保資料一致性非常重要。傳統的synchronized關鍵字對於公平性、立即獲取鎖定、等待特定時間獲取鎖等複雜場景缺乏彈性。 Java 1.5中引入了Lock、ReadWriteLock和StampedLock API來解決這些限制,並為開發人員提供了很好的控制來處理共享資源存取。它們是 java.util.concurrent 套件的一部分。

鎖定API

Lock API 是一個接口,提供以下方法來處理線程同步。

  • void lock() 用來取得鎖定。如果鎖不可用,則執行緒將被阻塞,直到取得鎖。
  • void lockInterruptically() 與lock()相同,但該執行緒可以中斷。
  • boolean tryLock() 如果取得鎖則回傳true;否則為假。如果沒有授予鎖,則執行緒不會被阻塞。
  • boolean tryLock(long timeout, TimeUnit unit) 與 tryLock() 相同,但只等待指定的時間。
  • voidunlock()釋放鎖。
  • Condition newCondition() 為執行緒提供在執行關鍵部分時等待某些條件發生的能力。

可重入鎖

  • ReentrantLock 類別實作了 Lock 介面。 
  • 可重入鎖允許執行緒多次取得鎖並多次釋放它。
  • 如果你想要公平策略,請使用 ReentrantLock 的參數化建構子。
  • 如果啟用公平性,它會確保等待時間最長的執行緒能夠存取鎖定。
  • 使用finally塊釋放鎖以避免死鎖情況。
ReentrantLock lock = new ReentrantLock(true); //fair lock
public void methodExecution() {
    lock.lock();
    try {
        // Critical section here
    } finally {
        lock.unlock();
    }
}
登入後複製
登入後複製

讀寫鎖定API

ReadWriteLock API 是一個接口,維護一對鎖來維護讀寫場景。如果沒有寫入者,讀鎖可以由多個執行緒同時持有。寫鎖是獨佔的。

  • Lock readLock() - 傳回用於讀取的鎖。
  • Lock writeLock() - 傳回用於寫入的鎖。

關鍵規則

  • 如果有讀鎖,則無法取得寫鎖。
  • 如果擁有寫鎖,則無法在任何其他執行緒中取得讀鎖。
  • 如果你有一個寫鎖,你可以在同一個執行緒中取得另一個寫鎖。
  • 當沒有其他讀取或寫入鎖定處於活動狀態時,允許寫鎖定。
  • 等待寫入鎖定時,不允許來自其他執行緒的新讀鎖定。

可重入讀寫鎖

  • ReentrantReadWriteLock 類別實作了 ReadWriteLock 介面。
  • 如果我們有更多的閱讀量而不是寫入量,那麼就很有用。

範例:在微服務通訊中,假設服務 B 需要來自服務 A 的 JWT。 JWT 由服務 A 生成,並且可以快取幾分鐘。在這種情況下ReentrantReadWriteLock會比較有用。如果令牌過期或即將過期,我們可以更新令牌。我在這裡不獲取讀鎖以避免讀飢餓。

ReentrantLock lock = new ReentrantLock(true); //fair lock
public void methodExecution() {
    lock.lock();
    try {
        // Critical section here
    } finally {
        lock.unlock();
    }
}
登入後複製
登入後複製

印記鎖定API

StampedLock 是在 Java 8 中引入的,它是一個類別。它支援三種鎖定模式並傳回用於釋放鎖定的標記。它允許鎖升級。

  1. 讀鎖允許多個執行緒並發讀取。
  2. Write Lock 傳回用於寫入的鎖。
  3. 樂觀讀鎖允許執行緒在不獲取傳統讀鎖的情況下進行讀取,從而避免爭用,從而提高效能。
  • long writeLock() 取得獨佔鎖,必要時阻塞直至可用。
  • void unlockWrite(long stamp) 釋放寫鎖。
  • long readLock() 取得讀鎖,如果正在進行寫入鎖定則阻塞。
  • void unlockRead(long stamp) 釋放讀鎖定。
  • long tryOptimisticRead() 傳回稍後可以驗證的標記,如果獨佔鎖定則傳回零。
  • boolean validate(long stamp) 如果自給定戳記發布以來尚未獨佔獲取鎖(寫鎖),則傳回 true;否則,錯誤。
  • long tryConvertToWriteLock(long stamp) 將讀鎖或樂觀鎖升級為寫鎖。阻塞直到可用。

重點:

  • 它是不可重入,這表示持有鎖的執行緒無法再次取得它。
  • 不支援條件。
  • 它不支持公平。
String jwt = JwtUtil.generateJwt();
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock writeLock = lock.writeLock();
Lock readLock = lock.readLock();

public String getJwt(String key, String value) {
    if (StringUtils.hasLength(jwt)) {
        if (JwtUtil.isJwtEligibleToRenew(jwt)) {
            generateJwt();
        }
    } else {
        generateJwt();
    }
    return this.jwt;
}

public void generateJwt() {
    this.writeLock.lock(); //write lock
    try {
        if (JwtUtil.isJwtEligibleToRenew(jwt)) {
            this.jwt = JwtUtil.generateJwt();
        }
    } finally {
        this.writeLock.unlock(); //release write lock
    }
}
登入後複製

樂觀的閱讀範例。這允許執行緒在不獲取傳統讀鎖的情況下進行讀取,從而避免了鎖爭用,從而提高了效能。如果在取得樂觀讀鎖時間後取得了任何寫鎖,validate() 將會傳回 false,否則傳回 true。

public void readAndWrite() {
    long l = this.stampedLock.readLock();
    try {
        //critical section
    } finally {
        this.stampedLock.unlock(l);
    }

    long w = this.stampedLock.writeLock();
    try {
        //critical section
    } finally {
        this.stampedLock.unlock(w);
    }
}
登入後複製

快樂編碼和學習! ! !

如有任何問題請留言。

以上是java中Lock API概述的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板