写点什么

java 中 synchronized 和 ReentrantLock 的加锁和解锁能在不同线程吗?如果能,如何实现?

  • 2023-06-21
    北京
  • 本文字数:1227 字

    阅读完需:约 4 分钟

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

发布于: 刚刚阅读数: 2
用户头像

公众号:福大大架构师每日一题 2021-02-15 加入

公众号:福大大架构师每日一题

评论

发布
暂无评论
java中synchronized和ReentrantLock的加锁和解锁能在不同线程吗?如果能,如何实现?_Java_福大大架构师每日一题_InfoQ写作社区