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是不可重入锁,所以在协程上的加锁和解锁没做限制。加锁和解锁可以不在同一协程,但要成对出现。

相关链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。