我有一个如下所示的同步方法:
static Object foo (Map m, String key) {
synchronized (m) {
//...
return m.get(key);
}
}
和另一种调用此方法的方法:
static void bar (Map m, Stirng key) {
synchronized (foo (m,key) ) {
//Is m still synchronized locked here?
//...
}
}
我的问题如上。由于synchronized块是foo的返回值,我想知道这些问题的答案:
答案 0 :(得分:7)
在这种情况下,
synchronized (foo (m,key) ) {
/* Critical section. */
}
...在关键部分,线程只对m.get(key)
的结果进行锁定。线程确实获得m
上的锁定,但它在从foo()
<返回之前被释放/ p>
答案 1 :(得分:1)
第二个例子同步foo返回的东西,但不同步其他任何东西,比如m。根据Java语言规范,当线程尝试进入同步块时,将评估synchronized关键字之后的parens中的表达式,结果是线程必须获取其监视器的对象。
同步取决于拥有共享锁,如果您的方法不共享相同的锁,那么它将无法工作。如果您需要代码来获取m上的锁定,您可以执行类似
的操作static void bar(Map m, String key) {
synchronized (m) {
synchronized (foo (m,key) ) {
//...
}
}
}
因为内部锁是可重入的(在外部块中获取锁定并不会阻止foo再次获取它)。