java.concurrent.ReentrantLock - 为什么我们想要多次获取相同的锁

时间:2013-09-03 15:30:21

标签: java multithreading reentrantlock

我知道如果使用ReentrantLock,它允许同一个线程多次获取相同的锁。在内部,它有一个计数器来计算锁定采集的数量。如果您两次获得相同的锁定,则需要将其释放两次。但我的问题是,如果有一次获得足够的话,为什么有人想多次获得锁?有人可以给我一个常见的用例吗?

4 个答案:

答案 0 :(得分:8)

考虑以下情况,您需要一组非原子的操作,即原子操作。例如,您可能希望设置数组的值,但在设置时返回其当前值。 (尝试 - 最后为了简洁而删除。)

final ReentrantLock lock = new ReentrantLock();

final Object[] objects = new Object[10]
public Object setAndReturnPrevious(int index, Object val){
   lock.lock();
      Object prev = get(index);
      set(index,val);
      return prev;
   lock.unlock();
}
public void set(int index, Object val){
    lock.lock();
         objects[index] = val;
    lock.unlock();
}
public Object get(index index){...}

如果ReentrantLock不可重入,则会在get(index)

处死锁

答案 1 :(得分:3)

假设在一个类中你有两个方法m1和m2,同步和m2都调用m1。 在这种情况下,如果线程a对m1进行了锁定并且不允许再次锁定,那么thresad将继续等待调用m2(因为它已经有锁定)

答案 2 :(得分:2)

考虑这个同步的例子。这同样适用于锁定,但代码更多。

synchronized int getSum() {
     return getValue() + getOtherValue();
}

synchronized int getValue() {
     return value;
}

synchronized int getOtherValue() {
     return value;
}

避免重入的唯一方法是创建每种方法的锁定和解锁版本。但是,如果你有两个实例A和B,那么怎么办?A调用B调用A. B如何知道不在A中调用同步方法。

答案 3 :(得分:1)

有些人认为应该避免重入锁定。在关键部分,您应该确切知道发生了什么。如果本地关键部分可能调用可能调用本地代码的外部代码,那么这看起来非常复杂并且可能存在危险。最好只有几个明确定义的关键部分只包含本地代码。