英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论