我正在尝试使用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提供了许多其他方法来实现线程安全(Lock,CountDownLatch,Semaphore,...),但是由于您所指的是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/