4

我正在尝试使用 AtomicInteger 变量作为锁。所以,想知道下面发布的代码是否是线程安全的。我知道 incrementAndGet() 是一个原子操作。但是,我不确定后续的 '==' 操作是否也是原子的(如果值在我进行比较时增加到 2 会怎样。)。所以发布这个问题来听听你的想法。

private AtomicInteger count = new AtomicInteger(0); //Shared variable
private final int max = 1;

if(count.incrementAndGet() == max) {
  //Do something
}
4

1 回答 1

3

由于incrementAndGet()是原子操作,因此最多可以有一个线程获取1结果(只要 AtomicInteger 的值未设置为低于 1)。这是由 AtomicInteger 保证的。虽然实际比较不是这个原子操作的一部分,但只有接收到的线程1才会运行到if块中。这是因为比较比较了 typeint的两个值:)incrementAndGet()max. AtomicInteger 在其中不起作用,因为int当内部状态发生变化时,原语不会改变它的值count。tl; dr:您的代码相当于:

final int val = count.incrementAndGet(); // (it makes no difference if val is not 'final`)
if (val == max) {
    // ...
}

Java 提供了许多其他方法来实现线程安全(LockCountDownLatchSemaphore,...),但是由于您指的是 AtomicInteger,我相信AtomicInteger.compareAndSet()更准确地满足您的要求:

if (count.compareAndSet(0, 1)) {
    // executed if count == 0
    count.set(0);
}
于 2018-09-20T23:57:18.487 回答