Java parallel volatile i++

Peter111 :

I have a global variable

volatile i = 0;

and two threads. Each does the following:

i++;
System.out.print(i);

I receive the following combinations. 12, 21 and 22.

I understand why I don't get 11 (volatile disallows the caching of i) and I also understand 12 and 22.

What I don't understand is how it is possible to get 21?

The only possible way how you can get this combination is that the thread that prints later had to be the first to increment i from 0 to 1 and then cached i==1. Then the other thread incremented i from 1 to 2 and then printed 2. Then the first thread prints the cached i==1. But I thought that volatile disallow caching.

Edit: After running the code 10,000 times I got 11 once. Adding volatile to i does not change the possible combinations at all.

markspace is right: volatile forbids caching i but i++ is not atomic. This means that i still gets sort of "cached" in a register during the incrementation.

r1 = i
//if i changes here r1 does not change
r1 = r1 + 1 
i = r1

This is the reason why 11 is still possible. 21 is caused because PrintStreams are not synchronized (see Karol Dowbecki's answer)

markspace :

Unfortunately ++ is not an atomic operation. Despite volatile not allowing caching, it is permitted for the JVM to read, increment, and then write as separate operations. Thus, the concept you are trying to implement just isn't workable. You need to use synchronized for its mutex, or use something like AtomicInteger which does provide an atomic increment operation.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=85336&siteId=1