此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)进行同步将防止出现这种竞争情况,因为线程将无法像上述那样进行交织。