1
次のコードは、あるスレッドが別のスレッドがすでに更新かもしれないcurrent
取得した後Javaで競合状態が発生しないで原子変数を同時に更新することはなぜ可能ですか?
AtomicInteger atomicInt = new AtomicInteger(0);
ExecutorService executor = Executors.newFixedThreadPool(20);
IntStream.range(0, 1000)
.forEach(i -> executor.submit(atomicInt::incrementAndGet));
は、我々はcurrent
が同期またはロックされていない見ることができますincrementAndGet
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
の実装である競合条件なしで動作します。
しかし、それは原子クラスが競合状態を回避するように思われます。
私の間違いを指摘できますか?
compareAndSet()はロックを使用します。ほとんどの実装では、 'compareAndSet()'は、ハードウェア(例えば、x86ハードウェア上のCMPXCHG命令)におけるロックを行う特別な命令を実行する。https://en.wikipedia.org/wiki/Compare-and-swap –