自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java的獨占鎖和共享鎖,你了解了么?

開發(fā) 前端
獨占鎖對于保護臨界區(qū)(critical sections)非常有用,臨界區(qū)是一段代碼,它訪問或修改共享資源,并且必須被串行執(zhí)行以防止數(shù)據(jù)不一致。然而,獨占鎖可能會降低并發(fā)性,因為它阻止了多個線程同時訪問被保護的資源。因此,在設計并發(fā)系統(tǒng)時,需要仔細權衡獨占鎖的使用。

昨天了不起帶著大家一起學習了關于這個樂觀鎖,悲觀鎖,遞歸鎖以及讀寫鎖,今天我們再來看看這個關于 Java 的其他的鎖,大家都了解 Java 的鎖有很多種,我們今天再來介紹四種鎖。

公平鎖

Java 中的公平鎖是一種多線程同步機制,它試圖按照線程請求鎖的順序來分配鎖。公平鎖的主要目標是避免“線程饑餓”問題,即某些線程長時間得不到執(zhí)行的情況。

在 Java 的 java.util.concurrent.locks 包中,ReentrantLock 是一個可重入的互斥鎖,它提供了公平鎖和非公平鎖兩種策略。當你創(chuàng)建一個 ReentrantLock 實例時,可以指定它是否為公平鎖:

// 創(chuàng)建一個公平鎖  
ReentrantLock fairLock = new ReentrantLock(true);

在公平鎖策略中,等待時間最長的線程將獲得鎖。公平鎖通過維護一個隊列來跟蹤等待鎖的線程,并按照它們進入隊列的順序為它們分配鎖。然而,需要注意的是,公平鎖并不能完全保證公平性,因為線程調(diào)度仍然受到操作系統(tǒng)和 JVM 的影響。

公平鎖的一個主要缺點是性能。由于需要維護一個隊列來跟蹤等待鎖的線程,并且在線程釋放鎖時需要喚醒等待隊列中的下一個線程,因此公平鎖通常比非公平鎖具有更高的開銷。此外,在高并發(fā)場景下,公平鎖可能會導致更高的上下文切換率,從而降低系統(tǒng)性能。

非公平鎖

其實我們在看到了上面的公平鎖之后,那么就很容易的去了解這個非公平鎖,因為非公平鎖是與公平鎖相對的一種多線程同步機制。在非公平鎖策略中,鎖的分配并不保證按照線程請求鎖的順序來進行。這意味著,即使有一個線程已經(jīng)等待了很長時間,新到來的線程仍然有可能立即獲得鎖。

非公平鎖通常具有更高的吞吐量,因為它們減少了維護等待隊列所需的開銷。當線程嘗試獲取鎖時,它不必檢查或加入等待隊列,而是直接嘗試獲取鎖。如果鎖當前可用,線程就可以立即獲得鎖并執(zhí)行,而不需要等待其他線程。

在 Java 的 java.util.concurrent.locks 包中,ReentrantLock 類的默認構造函數(shù)創(chuàng)建的就是一個非公平鎖:

// 創(chuàng)建一個非公平鎖  
ReentrantLock unfairLock = new ReentrantLock();

非公平鎖的優(yōu)勢在于它們通常能夠更有效地利用系統(tǒng)資源,特別是在高并發(fā)場景下。由于減少了線程間的切換和等待,非公平鎖通常能夠提供更高的性能。

然而,非公平鎖的一個潛在缺點是它們可能會導致線程饑餓。如果有一個或多個線程持續(xù)地被新到來的線程搶占,那么這些等待的線程可能會長時間得不到執(zhí)行。這種情況在高負載或資源競爭激烈的系統(tǒng)中尤其可能發(fā)生。

在選擇使用公平鎖還是非公平鎖時,應該根據(jù)應用程序的具體需求進行權衡。如果系統(tǒng)對公平性有嚴格要求,或者想要避免線程饑餓問題,那么公平鎖可能是一個更好的選擇。如果系統(tǒng)更關注性能,并且可以接受一定程度的不公平性,那么非公平鎖可能更加合適。

共享鎖

在Java中,共享鎖(Shared Lock)是一種允許多個線程同時讀取資源,但在寫入資源時只允許一個線程獨占的鎖。這種鎖通常用于提高讀取操作的并發(fā)性,因為讀取操作通常不會修改數(shù)據(jù),所以允許多個線程同時進行讀取是安全的。

Java的java.util.concurrent.locks包中的ReentrantReadWriteLock類就是一種實現(xiàn)了共享鎖和獨占鎖(排他鎖)機制的讀寫鎖。在這個鎖中,讀鎖是共享的,寫鎖是獨占的。

我們來看看示例代碼:

ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();  
ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();  
ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();  
  
// 讀取數(shù)據(jù)時獲取讀鎖  
readLock.lock();  
try {  
    // 讀取共享資源  
} finally {  
    readLock.unlock();  
}  
  
// 修改數(shù)據(jù)時獲取寫鎖  
writeLock.lock();  
try {  
    // 修改共享資源  
} finally {  
    writeLock.unlock();  
}

在上面的代碼中,多個線程可以同時獲取讀鎖來讀取數(shù)據(jù),但當一個線程獲取了寫鎖時,其他線程既不能獲取讀鎖也不能獲取寫鎖,直到寫鎖被釋放。

ReentrantReadWriteLock有兩種模式:公平模式和非公平模式。在公平模式下,等待時間最長的線程將優(yōu)先獲得鎖;而在非公平模式下,鎖的分配不保證任何特定的順序,新到來的線程可能立即獲得鎖。

要注意的是,盡管讀鎖是共享的,但寫鎖是獨占的,并且寫鎖具有更高的優(yōu)先級。這意味著當一個線程持有寫鎖時,其他線程無法獲取讀鎖或寫鎖。此外,如果一個線程正在讀取數(shù)據(jù),并且有其他線程請求寫鎖,那么寫線程將會被阻塞,直到所有讀線程釋放讀鎖。

ReentrantReadWriteLock的讀鎖和寫鎖都是可重入的,這意味著一個線程可以多次獲取同一個鎖而不會導致死鎖。

使用共享鎖可以顯著提高讀取密集型應用的性能,因為它允許多個讀取線程并發(fā)執(zhí)行,而寫入密集型應用可能會因為寫鎖的競爭而受到限制。

獨占鎖

在Java中,獨占鎖(Exclusive Lock)是一種同步機制,它確保在給定時間內(nèi)只有一個線程能夠訪問特定的資源或代碼塊。當一個線程持有獨占鎖時,其他試圖獲取同一鎖的線程將會被阻塞,直到持有鎖的線程釋放該鎖。

java.util.concurrent.locks包中的ReentrantLock就是一種獨占鎖(也被稱為排他鎖或互斥鎖)的實現(xiàn)。此外,synchronized關鍵字在Java中也被用作實現(xiàn)獨占鎖的一種方式。

我們看看獨占鎖的示例代碼:

import java.util.concurrent.locks.ReentrantLock;  
  
public class ExclusiveLockExample {  
    private final ReentrantLock lock = new ReentrantLock();  
    private int sharedData;  
  
    public void updateData(int newValue) {  
        lock.lock(); // 獲取獨占鎖  
        try {  
            // 在此區(qū)域內(nèi)只有一個線程能夠執(zhí)行  
            sharedData = newValue;  
        } finally {  
            lock.unlock(); // 釋放獨占鎖  
        }  
    }  
  
    public int readData() {  
        lock.lock(); // 獲取獨占鎖以進行讀取(雖然通常讀取操作可以使用讀鎖來允許多個線程并發(fā)讀?。? 
        try {  
            // 在此區(qū)域內(nèi)只有一個線程能夠執(zhí)行  
            return sharedData;  
        } finally {  
            lock.unlock(); // 釋放獨占鎖  
        }  
    }  
}

在這個例子中,updateData和readData方法都使用了獨占鎖來確保同時只有一個線程能夠訪問sharedData變量。

上面這個示例是使用的ReentrantLock的獨占鎖,既然我們說了 synchronized 關鍵字也是可以的,我們看看使用這個 synchronized 關鍵字的獨占鎖:

public class SynchronizedExample {  
    private int sharedData;  
  
    public synchronized void updateData(int newValue) {  
        // 在此區(qū)域內(nèi)只有一個線程能夠執(zhí)行  
        sharedData = newValue;  
    }  
  
    public synchronized int readData() {  
        // 在此區(qū)域內(nèi)只有一個線程能夠執(zhí)行  
        return sharedData;  
    }  
}

在synchronized這個例子中,updateData和readData方法都被聲明為synchronized,這意味著它們在同一時間內(nèi)只能由一個線程訪問。synchronized關鍵字提供了一種簡便的方式來實現(xiàn)獨占鎖,而不需要顯式地創(chuàng)建鎖對象。

獨占鎖對于保護臨界區(qū)(critical sections)非常有用,臨界區(qū)是一段代碼,它訪問或修改共享資源,并且必須被串行執(zhí)行以防止數(shù)據(jù)不一致。然而,獨占鎖可能會降低并發(fā)性,因為它阻止了多個線程同時訪問被保護的資源。因此,在設計并發(fā)系統(tǒng)時,需要仔細權衡獨占鎖的使用。

所以關于這四種鎖,你了解了么?

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2022-02-21 15:01:45

MySQL共享鎖獨占鎖

2024-06-06 09:03:37

MySQL數(shù)據(jù)庫共享鎖

2024-02-27 07:35:55

B-TreeB+TreeMySQL

2019-01-04 11:18:35

獨享鎖共享鎖非公平鎖

2023-08-17 14:10:11

Java開發(fā)前端

2022-05-05 21:06:33

人工智能計算機視覺自然語言處理

2022-05-06 16:31:27

人工智能自然語言生物特征識別

2023-11-27 00:48:46

displayvisibility

2021-11-26 08:07:16

MySQL SQL 語句數(shù)據(jù)庫

2024-05-15 09:23:45

MySQL排他鎖共享鎖

2018-07-31 10:10:06

MySQLInnoDB死鎖

2019-10-17 08:51:00

Java悲觀鎖Monitor

2023-10-26 07:09:30

Golangrune字符

2024-01-29 01:08:01

悲觀鎖遞歸鎖讀寫鎖

2023-05-15 09:39:10

Java監(jiān)視器鎖

2024-03-18 12:21:28

Java輕量級鎖重量級鎖

2020-09-16 07:56:28

多線程讀寫鎖悲觀鎖

2024-03-20 08:31:40

KotlinExtension計算

2022-03-24 13:36:18

Java悲觀鎖樂觀鎖

2019-11-28 16:00:06

重入鎖讀寫鎖樂觀鎖
點贊
收藏

51CTO技術棧公眾號