想象counter
为9
线程1做到这一点:
counter++; // counter = 10
线程2做到这一点:
counter++; // counter = 11
if(counter==10) // oops
现在,你可能认为你可以解决这个问题:
if(counter >= 10) counter -= 10;
但现在,如果两个线程都检查条件并发现它是真的,那么两个线程将计数器递减10(现在您的计数器为负)会发生什么情况。
或在更低的水平,counter++
实际上是三种操作:
- 获取
counter
- 添加一个
counter
- 商店
counter
所以:
- 线程1获取计数器
- 线程2获取计数器
- 两个线程都添加一个到他们的柜台
- 两个线程存储他们的柜台
在这种情况下,你希望计数器递增两次,但它只会增加一次。你可以把它想象成如果正在执行这个代码:
c1 = counter;
c2 = counter;
c1 = c1 + 1;
c2 = c2 + 1;
counter = c1; // Note that this has no effect since the next statement overrides it
counter = c2;
所以,你可以在一个块包装它,但使用AtomicInteger会更好,如果你只有几个线程:
public class counting {
private static AtomicInteger counter = new AtomicInteger(0);
public static void counterCheck() {
int value = counter.incrementAndGet();
// Note: This could loop for a very long time if there's a lot of threads
while(value >= 10 && !counter.compareAndSet(value, value - 10)) {
value = counter.get();
}
}
}
这实际上是接近代码典型的例子是*不*线程。 –
不是一个无关紧要的问题,而是两个无关的提示:(1)它不会编译[countCheck()']没有返回值。 (2)java有一个强大的命名规则,即**类名以大写字母**开头,您应该重命名:'counting' - >'Counting'。 – amit
@Amit-这不是我的原始代码。感谢您的建议,但。 – questborn