从这个 link ,我明白“由于 lock() 和 unlock() 方法调用是显式的,我们可以将它们移动到任何地方,建立任何锁定范围,从一行代码到跨越多个方法的范围”

所以我从上面的陈述中了解到的是

public class Test {
    Lock l = new ReentrantLock();

    void myMethod1() {
        l.lock();
        // Do my stuff here
    }

    void myMethod2() {
        // Do more stuff here
        l.unlock();
    }
}

所以基本上 1 可以依次调用 method1 和 method2 并假设调用是线程安全的。

我不确定上面所说的是否属实。

如果有人在我已经在执行 method1/method2 对时调用了 method2 怎么办?是不是把事情复杂化了。

我认为在从函数返回控制权之前,应该在函数本身中获取和释放锁。我的理解正确吗?

最佳答案

第一个问题的答案:



假设另一个线程调用 unlock() 对象 上的 ReentrantLock 方法,那么 IllegalMonitorStateException 将被抛出 。因为线程没有获取锁,并且当它尝试解锁时会出现异常。
它不会对获取锁的第一个线程的执行或锁定产生任何影响。

  • 同一主题:
  • 锁:如果正在获取锁的同一线程再次尝试获取锁,则锁计数器增加。
  • Unlock:如果正在获取锁的同一个线程尝试解锁,则锁计数器递减,一旦锁计数器变为 0,线程就会释放锁。
  • 不同的线程:
  • 锁:如果锁被另一个线程持有,那么当前线程将被禁用以进行线程调度并处于 hibernate 状态,直到获得锁,此时锁持有计数设置为 1。
  • 解锁:如果不同的线程在不持有锁时尝试 unlock,则抛出 IllegalMonitorStateException。

  • 这就是 ReentrantLock lock 和 unlock 要求你使用 try-catch 或 throw 机制的原因,因为它会抛出异常。

    阅读以下来自 ReentrantLock#unlock() 的摘录



    回答第二个问题:



    这就是 ReentrantLock 的全部目的,您可以将锁定机制扩展到其他方法,而同步块(synchronized block)和方法则无法做到这一点。从 ReentrantLock 看下面

    关于java - 了解锁作用域,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31405311/

    10-12 04:58