我正在尝试使用AtomicInteger变量作为锁。 因此,想知道下面发布的代码是否是线程安全的。我知道incrementAndGet()是一个原子操作。但是,我不确定后续的'=='操作是否也将是原子操作(如果我进行比较时,该值增加到2,该怎么办)。因此,发布此问题以听听您的想法。
private AtomicInteger count = new AtomicInteger(0); //Shared variable
private final int max = 1;
if(count.incrementAndGet() == max) {
//Do something
}
答案 0 :(得分:2)
由于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,因此我相信{{ 3}}对您的要求更准确:
if (count.compareAndSet(0, 1)) {
// executed if count == 0
count.set(0);
}