Java对象分配和锁定

Java对象分配和锁定,java,synchronization,locking,Java,Synchronization,Locking,考虑以下代码段: Object bar1 = new ... ; Object bar2 = new ... ; Object foo = (either bar1 or bar2) ; 现在,在程序的不同时间,foo可以是bar1或bar2。我只是想检查synchronized(foo)是否会锁定相应的bar1或bar2。考虑到Java中没有复制对象,这似乎是最有可能的情况。这是正确的吗 Object bar1 = new Object(); Object foo = ba

考虑以下代码段:

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


 Object foo = (either bar1 or bar2) ; 
现在,在程序的不同时间,foo可以是bar1或bar2。我只是想检查synchronized(foo)是否会锁定相应的bar1或bar2。考虑到Java中没有复制对象,这似乎是最有可能的情况。这是正确的吗

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

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

  • 线程1到达方法中,并且foo==bar1
  • 线程1到达同步块并锁定bar1
  • 线程2到达方法中,并且foo==bar2
  • 线程2到达同步块并锁定bar2
现在有2个线程同时运行同步块。我真的找不到你想要的理由。如果您这样做了,那么块可能不应该同步,您应该使用不同的锁定策略


另请参见。

是。您不是在引用上同步,而是在底层对象上同步

每个对象都有一个关联的监视器,当您使用
synchronized
时,您将锁定该监视器。发件人:

在Java虚拟机中,每个对象和类在逻辑上都是 与监视器关联的。对于对象,关联的监视器 保护对象的实例变量。上课时,班长 保护类的类变量


是的,它将锁定
foo
指向的任何对象。但是,我强烈建议您将
foo
设置为final,以避免出现以下情况:

Object foo = bar1;
synchronized(foo) {
   foo = bar2;
}

因为它会导致havok,多个线程会看到不同的锁。另请参见此问题:

+1一般来说,除了
最终
字段之外,同步任何内容都不是一个好主意。如果
bar1
bar2
需要同步,则应在内部同步。