5

我遇到了一些(生产!)代码,如下所示:

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

我希望这会受到各种可怕的竞争条件的影响,并且第二个线程可能会在创建新对象时进入这个块。我的 Java 印章不足以明确说明上述预期的行为,所以在我重构之前你们必须说些什么。

4

4 回答 4

4

这实际上可能没问题,具体取决于发生了什么。您需要了解更大的背景。同步将在some_object块开头指向的对象上进行。您的描述中没有足够的信息表明这是一个错误。

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

于 2012-05-24T23:09:58.493 回答
2

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

SomeObject saved = some_object;
synchronized(saved) {
  some_object = new SomeObject()
}
于 2012-05-24T23:12:53.130 回答
1

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

于 2012-05-24T23:22:42.517 回答
1

这很糟糕。同步最好用于最终类成员。

以线程安全方式创建对象的现代方法是在循环中使用 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;
   }
}
于 2012-05-25T00:11:24.130 回答