user3591466
user3591466

Reputation: 867

Why is it possible to update atomic variables concurrently without race condition in Java?

The following code works without race condition

AtomicInteger atomicInt = new AtomicInteger(0);

ExecutorService executor = Executors.newFixedThreadPool(20);

IntStream.range(0, 1000)
    .forEach(i -> executor.submit(atomicInt::incrementAndGet));

Here is the implementation of incrementAndGet

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}

We can see current is not synchronized or locked, after one thread get the current another thread might already update the current.

But it seems like atomic class avoids race condition some how.

Can someone point out my mistake?

Upvotes: 2

Views: 406

Answers (1)

johnnyaug
johnnyaug

Reputation: 1163

compareAndSet sets the value (and returns true) if and only if the first parameter is equal to the AtomicInteger's current value.

That is, if another thread had already changed the value, then current would not be equal to the current value, and the loop would run once more.

From the documentation of compareAndSet(int expect, int update):

Atomically sets the value to the given updated value if the current value == the expected value.

Upvotes: 3

Related Questions