Why my increment operation is atomic in multithread context?

2 weeks ago 25
ARTICLE AD BOX

I'm trying to increment 2 times by 1000 times the shared counter

import kotlin.concurrent.thread class MultiThreads { var counter = 0 fun main(){ val thread1 = thread { (1..1000).forEach { _ -> counter++ println("T1: $counter") } } val thread2 = thread { (1..1000).forEach { _ -> counter++ println("T2: $counter") } } thread1.join() thread2.join() println("counter=$counter") } }

the result is (console tail):

...........

T1: 1998

T1: 1999

T1: 2000

counter=2000

---

AFAIK it's supposed to be less 2000, isn't it?

J.J. Beam's user avatar

7

Try doing it with 10000 instead of 1000.

2026-01-07 05:00:27 +00:00

Commented 1 hour ago

"AFAIK it's supposed to be less 2000, isn't it?" -- It isn't "supposed to", per se. Improperly sharing state between threads like this leads to undefined behavior. Sometimes your code will end with counter being 2000, other times the final value will be less.

2026-01-07 05:13:54 +00:00

Commented 1 hour ago

Yes. You've just got lucky.

2026-01-07 05:14:00 +00:00

Commented 1 hour ago

Note those println calls inside your loops involve synchronization (an implementation detail, if I'm not mistaken). While that certainly in no way guarantees the final value of counter will be 2000, the synchronization may make it more likely that it will (a happens-before relationship is being created between the two threads, though not with regards to counter, and the synchronization will mess with the thread timings).

2026-01-07 05:42:07 +00:00

Commented 1 hour ago

I also think that println is relatively slow, making it less likely that counter++ will actually experience a data race. Thus this particular code doesn't tend to show errors. Remove the println from the loop and place it after the loop, so it's only printed once. You may see more frequent errors then.

2026-01-07 05:44:51 +00:00

Commented 1 hour ago

Read Entire Article