问题描述
在下面给出的代码中。我怎么知道可重入锁已锁定哪个对象?
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();
}
}
}
在上面的示例中,哪个对象被锁定了?如果我想使用可重入锁显式锁定obj1和obj2,那怎么可能?
解决方法
Lock lock = new ReentrantLock(); // Which object is getting locked here? lock.lock();
lock
对象被锁定在那里。
我认为也许您误解了synchronized(ob1) {...}
的工作。它不会阻止其他线程使用obj1
。唯一阻止的事情是,它防止其他线程同时在同一对象上同步。
Java(以及大多数其他编程语言/库)中的锁被称为advisory locks。 “咨询”是指,程序员必须知道应该由锁保护哪些数据,并且程序员负责确保程序中的任何线程都不会使用该数据,除非线程已锁定了锁。
仅供参考:Java中的一种“干净”的做法是通过这种方式使用synchronized
:
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 ...;
}
}
此模式允许您发布MyClass
的实例,而不会将lock
对象暴露给调用者。这也很清楚lock
对象本身与受锁保护的数据/关系之间的区别。
如果将来将来需要使用此模式,则可以轻松地从使用synchronized
切换为使用Lock
对象。