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();
}
}
}
運作結果如下:
在這裡插入圖檔描述
根據運作結果可以看出,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)
}
在這裡插入圖檔描述
根據運作結果可以看出,sync.Mutex的加鎖和解鎖在代碼層面上可以實作,運作也正常。說明sync.Mutex支援同一把鎖的加鎖和解鎖能在不同協程。
綜上所述:go中sync.Mutex的加鎖和解鎖能在不同線程。
總結:
java中synchronized和ReentrantLock都是可重入鎖,是以線上程上的加鎖和解鎖會做限制,加鎖和解鎖必須在同一線程,并且成對出現。
go的sync.Mutex是不可重入鎖,是以在協程上的加鎖和解鎖沒做限制。加鎖和解鎖可以不在同一協程,但要成對出現。
福大大架構師每日一題java當死,golang當立。最新面試題,涉及golang,rust,mysql,redis,雲原生,算法,分布式,網絡,作業系統。572篇原創内容
公衆号