基于该对象在同步块内分配对象(Java)

时间:2012-05-24 23:06:08

标签: java synchronization

我遇到了一些(生产!)代码,看起来像下面的代码段:

synchronized(some_object) {
    some_object = new some_object()
}

我希望这会受到各种可怕的竞争条件的影响,并且第二个线程可能会进入此块,创建一个新对象。我的Java排骨不够好,无法明确说明上面的预期行为,所以好奇你们重构之前你们要说的话。

4 个答案:

答案 0 :(得分:4)

这实际上可以是正常的,具体取决于发生了什么。您需要了解更大的背景。同步将在块的开头由some_object指向的对象上。您的描述中没有足够的信息来确定这是一个错误。

同步本身就可以正常工作。

答案 1 :(得分:2)

弗朗西斯说,这可能不是问题。您的代码段相当于:

SomeObject saved = some_object;
synchronized(saved) {
  some_object = new SomeObject()
}

答案 2 :(得分:1)

同步位于进入同步块时引用的对象上。将引用指向同步块内的另一个对象根本不会影响同步。它仍然在“旧”对象上同步。

答案 3 :(得分:1)

这很糟糕。 synchronized最适用于最终的成员。

以线程安全方式创建对象的现代方法是在循环中使用AtomicReference compareAndSet,如Goetz的Java Concurrency in Action(第15章)中所讨论的。这不会阻塞您的线程,并且提供比同步块更高的性能。

private final AtomicReference<SomeObject> someObject = new AtomicReference<>();


void buildIt() {
   SomeObject obj = new SomeObject();
   SomeObject current = someObject.get();  //probably null, but doesn't matter
   while (true) {
      if (someObject.compareAndSet(current, obj)) 
          break;
   }
}