在Java的可重入锁(Reentrant Lock)中,与`synchronized( object )`相对应的是什么?

huangapple go评论61阅读模式
英文:

What is the equivalent of synchronized( object ) in Reentrant lock in Java?

问题

在下面的代码中,我如何知道哪个对象被 Reentrant Lock 锁定?

Public class Test {

    Map obj1 = new HashMap();
    Object ob2 = new Object();

    void Method() {

        //First
        synchronized(ob1) { // Locks obj1

        }
        synchronized(ob2) { // Locks obj2

        }

        //Second
        Lock lock = new ReentrantLock(); // Which object is getting locked here? 
        lock.lock();
        try {

        } finally {
            lock.unlock();
        }

    }

}

在上面的示例中,哪个对象被锁定了?如果我想使用 Reentrant Lock 显式地锁定 obj1 和 obj2,该如何实现?

英文:

In the code given below. How can I know which object Reentrant Lock has locked ?

Public class Test {

    Map obj1 = new HashMap();
    Object ob2 = new Object();

    void Method() {

        //First
        synchronized(ob1) { // Locks obj1

        }
        synchronized(ob2) { // Locks obj2

        }

        //Second
        Lock lock = new ReentrantLock(); // Which object is getting locked here? 
        lock.lock();
        try {

        } finally {
            lock.unlock();
        }

    }

}

In the above example which Object is getting locked ? If I want to explicitly lock obj1 and obj2 using Reentrant lock how is it possible ?

答案1

得分: 4

The `lock` object is getting locked there.

I think maybe you misunderstand what `synchronized(ob1) {...}` does. It does _not_ prevent other threads from using `obj1`. The only thing it prevents is, it prevents other threads from being synchronized on the same object at the same time.

Locks in Java (and in most other programming languages/libraries) are so-called [_advisory locks_](https://en.wikipedia.org/wiki/Lock_(computer_science)). "Advisory" means, the programmer has to know what data are supposed to be protected by the lock, and the programmer is responsible for ensuring that no thread in the program ever uses that data except when the thread has locked the lock.

----------------------------

FYI: A "clean" practice in Java is to use `synchronized` in this way:

    class MyClass {

        private final Object lock = new Object();
        private TypeA sharedMemberVariable_a;
        private TypeB sharedMemberVariable_b;
        ...

        public SomeType someMethod() {
            ...
            synchronized(lock) {
                ...access shared member variables...
            }
            return ...;
        }
    }

This pattern allows you to publish instances of `MyClass` without exposing the `lock` object to callers.  It also makes very clear the distinction between the `lock` object itself, and the data/relationships that are protected by the lock.

The pattern also makes it trivially easy to switch from using `synchronized` to using a `Lock` object if you need to do so in the future.
英文:

> Lock lock = new ReentrantLock(); // Which object is getting locked here?
> lock.lock();

The lock object is getting locked there.

I think maybe you misunderstand what synchronized(ob1) {...} does. It does not prevent other threads from using obj1. The only thing it prevents is, it prevents other threads from being synchronized on the same object at the same time.

Locks in Java (and in most other programming languages/libraries) are so-called advisory locks. "Advisory" means, the programmer has to know what data are supposed to be protected by the lock, and the programmer is responsible for ensuring that no thread in the program ever uses that data except when the thread has locked the lock.


FYI: A "clean" practice in Java is to use synchronized in this way:

class MyClass {

    private final Object lock = new Object();
    private TypeA sharedMemberVariable_a;
    private TypeB sharedMemberVariable_b;
    ...

    public SomeType someMethod() {
        ...
        synchronized(lock) {
            ...access shared member variables...
        }
        return ...;
    }
}

This pattern allows you to publish instances of MyClass without exposing the lock object to callers. It also makes very clear the distinction between the lock object itself, and the data/relationships that are protected by the lock.

The pattern also makes it trivially easy to switch from using synchronized to using a Lock object if you need to do so in the future.

huangapple
  • 本文由 发表于 2020年9月28日 22:06:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/64103796.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定