天天看點

java中synchronized和ReentrantLock的加鎖和解鎖能在不同線程嗎

作者:福大大架構師每日一題

java中synchronized和ReentrantLock的加鎖和解鎖能在不同線程嗎?如果能,如何實作?

答案2023-06-21:

java的:

這個問題,我問了一些人,部分人是回答得有問題的。synchronized這是個關鍵字,加鎖和解鎖不是直接用代碼實作,是以在代碼層面上就杜絕了加鎖和解鎖不在同一個線程得情況。可以這麼說,synchronized是無法實作同一把鎖的加鎖和解鎖在不同線程。

ReentrantLock的加鎖和解鎖,是在代碼層面實作的,是以是可以寫出這樣的代碼,如下:

package com.hikvision;

import java.util.concurrent.locks.ReentrantLock;

public class Application {
    private static ReentrantLock lock = new ReentrantLock();
    public static void main(String[] args) {
        // 線程1加鎖
        Thread thread1 = new Thread(() -> {
            lock.lock();
            try {
                System.out.println("Thread 1 lock.");
            } finally {
                lock.unlock();
            }
        });

        // 線程2解鎖
        Thread thread2 = new Thread(() -> {
            lock.unlock();
            System.out.println("Thread 2 unlock.");
        });

        thread1.start();
        try {
            Thread.sleep(1000); // 等待1秒,確定線程1先執行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread2.start();
        try {
            Thread.sleep(1000); // 等待1秒,確定線程2先執行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}           

運作結果如下:

java中synchronized和ReentrantLock的加鎖和解鎖能在不同線程嗎

在這裡插入圖檔描述

根據運作結果可以看出,ReentrantLock的加鎖和解鎖在代碼層面上可以實作,但是運作會報異常。說明ReentrantLock不支援同一把鎖的加鎖和解鎖能在不同線程。

綜上所述:java中synchronized和ReentrantLock的加鎖和解鎖不能在不同線程。

go的:

go的sync.Mutex的加鎖和解鎖能在不同協程嗎?如果能,如何實作?

sync.Mutex的加鎖和解鎖,是在代碼層面實作的,是以是可以寫出這樣的代碼,如下:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    // 加鎖和解鎖可以不在同一個協程
    var m sync.Mutex
    m.Lock()
    fmt.Println("加鎖成功")
    go func() {
        time.Sleep(time.Second * 5)
        m.Unlock()
        fmt.Println("解鎖成功")
    }()
    time.Sleep(time.Hour)
}           
java中synchronized和ReentrantLock的加鎖和解鎖能在不同線程嗎

在這裡插入圖檔描述

根據運作結果可以看出,sync.Mutex的加鎖和解鎖在代碼層面上可以實作,運作也正常。說明sync.Mutex支援同一把鎖的加鎖和解鎖能在不同協程。

綜上所述:go中sync.Mutex的加鎖和解鎖能在不同線程。

總結:

java中synchronized和ReentrantLock都是可重入鎖,是以線上程上的加鎖和解鎖會做限制,加鎖和解鎖必須在同一線程,并且成對出現。

go的sync.Mutex是不可重入鎖,是以在協程上的加鎖和解鎖沒做限制。加鎖和解鎖可以不在同一協程,但要成對出現。

java中synchronized和ReentrantLock的加鎖和解鎖能在不同線程嗎

福大大架構師每日一題java當死,golang當立。最新面試題,涉及golang,rust,mysql,redis,雲原生,算法,分布式,網絡,作業系統。572篇原創内容

公衆号