在 Brian Goetz 的Java Concurrency in Practice 中,有一个例子如下:
public class NumberRange {
// INVARIANT: lower <= upper
private final AtomicInteger lower = new AtomicInteger(0);
private final AtomicInteger upper = new AtomicInteger(0);
public void setLower(int i) {
// Warning -- unsafe check-then-act
if (i > upper.get())
throw new IllegalArgumentException(
"can't set lower to " + i + " > upper");
lower.set(i);
}
public void setUpper(int i) {
// Warning -- unsafe check-then-act
if (i < lower.get())
throw new IllegalArgumentException(
"can't set upper to " + i + " < lower");
upper.set(i);
}
public boolean isInRange(int i) {
return (i >= lower.get() && i <= upper.get());
}
}
我知道上面的代码容易出现竞争条件。
然后他解释如下:
像这样的多变量不变量创建了原子性要求:必须在单个原子操作中获取或更新相关变量。您不能更新一个,释放并重新获取锁,然后更新其他的,因为这可能涉及在释放锁时使对象处于无效状态。
我从这一段中了解到,如果我们创建setUpper和setLower函数synchronized,那么也会有对象可能达到无效状态的情况。但是,我认为如果两个函数都是同步的,那么只有一个线程可以执行其中一个函数,并且每个函数都必须检查不变量。我们怎么可能处于无效状态。任何人都可以用一个例子来演示。我在这里缺少什么?
如果我理解正确,那么这条线的意义是什么:
您不能更新一个,释放并重新获取锁,然后更新其他的,因为这可能涉及在释放锁时使对象处于无效状态。
Helenr
相关分类