可重入锁是对象级锁还是Class级锁?

Is Reentrant Lock a Object level lock or Class level lock?

我在很多关于可重入锁的教程中看到,他们创建了一个新的可重入锁并注入了资源,在try/finally块中调用了可重入锁的锁定和解锁。我不明白这个锁和线程中使用的资源之间的联系。下面是重入锁教程的例子

资源代码

public class Resource {

    public void doSomething(){
        //do some operation, DB read, write etc
    }
    
    public void doLogging(){
        //logging, no need for thread safety
    }
}

线程声明代码中正在使用的资源

public class ConcurrencyLockExample implements Runnable{

    private Resource resource;
    private Lock lock;
    
    public ConcurrencyLockExample(Resource r){
        this.resource = r;
        this.lock = new ReentrantLock();
    }
    
    @Override
    public void run() {
        try {
            if(lock.tryLock(10, TimeUnit.SECONDS)){
            resource.doSomething();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            //release lock
            lock.unlock();
        }
        resource.doLogging();
    }
}

谁能解释一下这如何防止多个线程同时访问给定资源导致竞争条件??? 此可重入锁是在资源中创建对象级锁还是 Class 级锁???

在某种意义上,ReentrantLock 既不是 class-level 也不是 object-level 锁。从更实际的意义上讲,它与它们中的任何一个都相同。

真的,您应该忘掉“class 级别”和“对象级别”锁定。这些不是有用的区别。

您可以使用 任何 对象作为 synchronized(lock){...} 块中的 lock。 “对象级”锁定只是意味着,在 class C 的某些方法中,您选择的对象是 class 的一个实例;而“class级别”表示你选择使用C.class作为锁定对象。

但是,您也可以使用其他对象*,无论您为 lock 选择什么对象,synchronized(lock) 的行为都是一样的。


* 这是经验丰富的软件开发人员经常使用的模式:

public class C {
    private final Object lock = new Object();

    public MyType myMethod(...) {
        ...
        synchronized(lock) {
            ...
        }
        ...
    }
}

使用 private 对象的原因是一些使用 class C 的客户端代码的作者可能会使用 C 的实例作为锁.这不是一个聪明的主意,但没有什么能阻止他们这样做。如果两个不同的作者选择使用同一个对象作为锁,则可能会出现不可预见的交互(例如,在最坏的情况下,会出现死锁)。但是 class C 的作者通过使用避免了这个问题其他 classes.

无法访问的 lock 对象