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

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

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

最佳答案

由于incrementAndGet()是原子操作,因此最多一个线程将获得1作为结果(只要AtomicInteger的值不小于1)。这由AtomicInteger保证。尽管实际的比较不是此原子操作的一部分,但是只有收到1的线程才会运行到if块中。这是因为比较比较了int类型的两个值: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);
}

关于java - AtomicInteger和Compare操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52434733/

10-09 01:47