【问题标题】:Recursive Synchronization vs Recursive Reentrant Lock递归同步与递归可重入锁
【发布时间】:2023-04-18 17:52:01
【问题描述】:

我知道线程可以获取自己拥有的监视器,即在 Java 中,同步锁是 reentrant,如下例所示。

我的问题是如果我使用java.util.concurrent.locks.ReentrantLock API 是否会产生相同的结果,我们是否可以在同步中出现死锁但在java.util.concurrent.locks.ReentrantLock 中永远不会出现

例如

  final Object[] objects = new Object[10]

    public synchronized Object setAndReturnPrevious(int index, Object val) {
        lock.lock();//If i use this will it be same as above synchronization
        set(index, val);
        lock.unlock()//;
    }

    public synchronized void set(int index, Object val) {
        lock.lock();//
        objects[index] = val;
        lock.unlock();//
    }

【问题讨论】:

  • 您是否在询问 lock 是否与您的示例中的 this 的监视器在同一监视器上同步?如果是这样,答案是否定的——就像lock2.lock() 也不会与lock.lock() 共享同一个监视器。

标签: java multithreading reentrantlock


【解决方案1】:

如果您查看 Java 文档 (here) 并且要点非常清楚(强调我的):

具有相同基本行为的可重入互斥锁和 语义作为使用同步访问的隐式监视器锁 方法和语句,但具有扩展功能。一种 ReentrantLock 归最后成功锁定的线程所有,但是 还没有解锁。调用锁的线程将成功返回 获取锁,当锁不属于另一个线程时。 如果当前线程已经拥有,方法将立即返回 锁定

主要的一点是它们都具有相同的概念,但是ReentrantLock lock 为lock()/unlock()/etc 提供了其他方法。您可以显式使用它们的方法在不同的代码块(方法)中。

【讨论】:

    【解决方案2】:

    同步锁和重入锁是一样的。如果你想要更多的控制并且想要解决复杂的同步问题,那么重入锁是最好的选择。它为隐式同步添加了额外的功能,例如**支持条件变量、锁定公平等** 作为参考检查Java Threads 3rd Ed - Chapter 3 and Onwards

    【讨论】: