article讨论Java的“synchronized”关键字。

  ...
  private int foo;
  public synchronized int getFoo() { return foo; }
  public synchronized void setFoo(int f) { foo = f; }

如果调用者想增加foo属性,则以下代码不是线程安全的:
  ...
  setFoo(getFoo() + 1);

如果两个线程尝试同时增加foo,则结果可能是foo的值增加1或2,具体取决于时间。

现在,我的问题是:

最佳答案

这是先检查后竞赛的条件示例。

场景可能会如下所示:

Thread-1 getFoo() returns 0
Thread-2 getFoo() returns 0
Thread-2 setFoo(1)
Thread-1 setFoo(1)

这意味着两个线程已尝试递增foo,但其效果仅是递增一次。

正如其他答案所确定的那样,将增量与锁定在与getFoo()和setFoo()相同的对象上的同步块(synchronized block)进行同步将防止出现这种竞争情况,因为线程将无法像上述那样进行交织。

09-11 16:19