Java对象分配和锁定

时间:2012-08-21 10:42:19

标签: java synchronization locking

考虑以下代码段:

 Object bar1  = new ... ; 
 Object bar2 = new ... ; 


 Object foo = (either bar1 or bar2) ; 

现在,foo在程序的不同时间可以是bar1或bar2。我只想检查synchronized(foo)是否会锁定相应的bar1或bar2。这似乎是最有可能的情况,因为对象不是用Java复制的。这是对的吗?

3 个答案:

答案 0 :(得分:6)

Object bar1 = new Object();
Object foo = bar1;
synchronized(foo) {
    ...
}

将锁定foo == bar1

然而,这是一个奇怪且容易出错的结构。例如:

  • 线程1到达您的方法并且foo == bar1
  • 线程1到达同步块并锁定在bar1
  • 线程2到达您的方法并且foo == bar2
  • 线程2到达同步块并锁定在bar2

现在你有2个线程同时运行你的synchronized块。我真的找不到你想要的原因。如果你这样做,那么该块可能不应该同步,你应该使用不同的锁定策略。

另见this related post

答案 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?