可重入鎖和不可重入鎖的區別

一、可重入鎖與不可重入鎖的區別

可重入鎖和不可重入鎖的最大區別在於,可重入鎖允許同一個線程在獲得鎖之後再次獲得該鎖,而不可重入鎖不允許。

在使用不可重入鎖時,如果一個線程已經獲得該鎖,那麼在該線程釋放該鎖之前,其他所有線程都無法獲得這個鎖。而在使用可重入鎖時,如果一個線程已經獲得鎖,那麼在該線程釋放該鎖之前,它可以再次獲得該鎖而不會被阻塞。

二、可重入鎖的使用場景

可重入鎖通常應用於遞歸或者嵌套的代碼中。在代碼嵌套調用的過程中,如果使用不可重入鎖,那麼程序將會阻塞,可能會導致死鎖現象的發生。

舉例來說,在使用不可重入鎖時,如果在一個線程已經獲得鎖的情況下,又嘗試獲得該鎖,那麼這個線程將會被一直阻塞,直到另外一個線程釋放該鎖。而在使用可重入鎖時,同一個線程可以多次獲得鎖,因此不會導致死鎖現象的發生。

三、可重入鎖的實現原理

可重入鎖最常用的實現方式是通過計數器來實現的,每次獲得鎖時,計數器加1,每次釋放鎖時,計數器減1。只有當計數器為0時,其他線程才有機會獲得該鎖。這樣就能夠保證同一個線程可以多次獲得該鎖,而其他線程只有在該鎖被徹底釋放時才能獲得該鎖。

四、synchronized可重入鎖

在Java語言中,synchronized關鍵字是一種可重入鎖。這意味着如果一個線程已經獲得了某個對象上的synchronized鎖,那麼它可以再次獲得該對象鎖而不會被阻塞。

synchronized鎖的實現方式並不是通過計數器來實現的。它是通過線程持有的對象監視器(也可以稱為鎖對象)來實現的。當線程請求進入一段同步代碼時,如果該鎖沒有被其他線程佔用,那麼該線程會獲得該鎖,同時鎖對象的計數器會+1。如果同一線程再次請求該鎖,那麼線程可以再次獲得該鎖,同時計數器也會再次+1。當線程執行完同步代碼塊並釋放鎖時,該線程持有的鎖對象的計數器會-1。只有當該計數器的值為0時,鎖對象才會被解鎖,這樣其他線程才有機會獲得該鎖。

五、可重入鎖和不可重入鎖的區別

1、可重入鎖允許同一個線程在獲得鎖之後再次獲得該鎖,而不可重入鎖不允許。

2、在使用不可重入鎖時,如果一個線程已經獲得該鎖,那麼在該線程釋放該鎖之前,其他所有線程都無法獲得這個鎖。而在使用可重入鎖時,如果一個線程已經獲得鎖,那麼在該線程釋放該鎖之前,它可以再次獲得該鎖而不會被阻塞。

3、可重入鎖通常用於遞歸嵌套的代碼中,而不可重入鎖一般只用於獨佔式地獲得資源。

示例代碼

// 可重入鎖的示例
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {
    private static final ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    work();
                }
            }).start();
        }
    }

    private static void work() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "獲得了鎖");
            nestedWork();
        } finally {
            lock.unlock();
        }
    }

    private static void nestedWork() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "再次獲得了鎖");
        } finally {
            lock.unlock();
        }
    }
}

// 不可重入鎖的示例
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class NonReentrantLockDemo {
    private static final Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                work();
            }
        }, "Thread-A").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                work();
            }
        }, "Thread-B").start();
    }

    private static void work() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "獲得了鎖");
            nestedWork();
        } finally {
            lock.unlock();
        }
    }

    private static void nestedWork() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "嘗試獲得鎖但被阻塞了");
        } finally {
            lock.unlock();
        }
    }
}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/199136.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-04 19:14
下一篇 2024-12-04 19:14

相關推薦

  • Python中new和init的區別

    new和init都是Python中常用的魔法方法,它們分別負責對象的創建和初始化,本文將從多個角度詳細闡述它們的區別。 一、創建對象 new方法是用來創建一個對象的,它是一個類級別…

    編程 2025-04-29
  • Sublime Test與Python的區別

    Sublime Text是一款流行的文本編輯器,而Python是一種廣泛使用的編程語言。雖然Sublime Text可以用於編寫Python代碼,但它們之間有很多不同之處。接下來從…

    編程 2025-04-29
  • Shell腳本與Python腳本的區別

    本文將從多個方面對Shell腳本與Python腳本的區別做詳細的闡述。 一、語法差異 Shell腳本和Python腳本的語法存在明顯差異。 Shell腳本是一種基於字符命令行的語言…

    編程 2025-04-29
  • Python中while語句和for語句的區別

    while語句和for語句是Python中兩種常見的循環語句,它們都可以用於重複執行一段代碼。然而,它們的語法和適用場景有所不同。本文將從多個方面詳細闡述Python中while語…

    編程 2025-04-29
  • Web程序和桌面程序的區別

    Web程序和桌面程序都是進行軟件開發的方式,但是它們之間存在很大的區別。本文將從多角度進行闡述。 一、運行方式 Web程序運行於互聯網上,用戶可以通過使用瀏覽器來訪問它。而桌面程序…

    編程 2025-04-29
  • TensorFlow和Python的區別

    TensorFlow和Python是現如今最受歡迎的機器學習平台和編程語言。雖然兩者都處於機器學習領域的主流陣營,但它們有很多區別。本文將從多個方面對TensorFlow和Pyth…

    編程 2025-04-28
  • MySQL bigint與long的區別

    本文將從數據類型定義、存儲空間、數據範圍、計算效率、應用場景五個方面詳細闡述MySQL bigint與long的區別。 一、數據類型定義 bigint在MySQL中是一種有符號的整…

    編程 2025-04-28
  • 麥語言與Python的區別

    麥語言和Python都是非常受歡迎的編程語言。它們各自有自己的優缺點和適合的應用場景。本文將從語言特性、語法、生態系統等多個方面,對麥語言和Python進行詳細比較和闡述。 一、語…

    編程 2025-04-28
  • Python與C語言的區別和聯繫

    Python與C語言是兩種常用的編程語言,雖然兩者都可以用於編寫軟件程序,但是它們之間有很多不同之處。本文將從多個方面對Python與C語言的區別和聯繫進行詳細的闡述。 一、語法特…

    編程 2025-04-28
  • Python中深拷貝和淺拷貝的區別

    本文將從以下幾個方面對Python中深拷貝和淺拷貝的區別做詳細的闡述,包括:拷貝的含義、變量和對象的區別、淺拷貝的示例、深拷貝的示例、可變對象和不可變對象的區別、嵌套的數據結構以及…

    編程 2025-04-28

發表回復

登錄後才能評論