考虑以下代码段:
Object bar1 = new ... ;
Object bar2 = new ... ;
Object foo = (either bar1 or bar2) ;
现在,foo在程序的不同时间可以是bar1或bar2。我只想检查synchronized(foo)是否会锁定相应的bar1或bar2。这似乎是最有可能的情况,因为对象不是用Java复制的。这是对的吗?
答案 0 :(得分:6)
Object bar1 = new Object();
Object foo = bar1;
synchronized(foo) {
...
}
将锁定foo
== bar1
。
然而,这是一个奇怪且容易出错的结构。例如:
现在你有2个线程同时运行你的synchronized块。我真的找不到你想要的原因。如果你这样做,那么该块可能不应该同步,你应该使用不同的锁定策略。
答案 1 :(得分:2)
是。您没有在引用上进行同步,而是在底层对象。
上进行同步每个对象都有一个关联的监视器,当你使用synchronized
时,你就锁定了它。来自here:
在Java虚拟机中,每个对象和类都是逻辑上的 与监视器相关联。对于对象,关联的监视器 保护对象的实例变量。对于课程,监视器 保护类的类变量
答案 2 :(得分:2)
是的,它会锁定foo
指向的任何对象。但是,我强烈建议你让foo
最终避免这样的事情:
Object foo = bar1;
synchronized(foo) {
foo = bar2;
}
因为它会导致havok有几个线程看到不同的锁。另请参阅此问题:Locking on a mutable object - Why is it considered a bad practice?