Java - Happens Before - Volatile

I have the code below

class VolatileCount {
    volatile int count;
    Object lock = new Object();

    public void increment() {

        synchronized (lock) {
            count = count + 1;
        }
        System.out.print(" " + count);
    }

}

If I call increment()on the same object from multiple threads, I get the following result (may differ on your computer)

2 3 2 5 4 8 8 6 11 13 10 9 15 14 12 20 19

Looking at the repeated numbers, which, it seems to me, happen, it seems that they are broken, because, looking at the first three numbers (2 3 2), if the stream sees 3, an increment occurs, and since the variable is variable, its value must be 3 or more, but cannot be 2 in any thread.
However, the print line seems to have been reordered here, is it right to reorder this line? What am I missing here? I am running JDK 7 (Eclipse)

+4
4

, "2 3 2"

  • X i ( 1)
  • Y i ( 2)
  • X i (X 2)
  • Y i (Y 2)
  • Y ( 2)
  • Z i, i, i ( 3)
  • X ( 2)

: System.out.print(" " + count) . .

, :

public void increment() {
    int localCount;
    synchronized (lock) {
        count = count + 1;
        localCount = count; // volatile load
    }
    System.out.print(" " + localCount);
}

. , , print .

. , System.out.print(" " + count).

  • X i
  • Thread X print count 2.
  • Thread X Thread Y, i
  • Thread Y i ( 3), , .
  • Y, Thread X print , 2.

, , "3 2 4".

, :

  • X i ( 2)
  • Y i ( 3)
  • X i ( 3)
  • Y i ( 3)
+7

2 . , - 1 . , 2, , 2, count (now 2) . 2 2

:

  • A 1
  • Thread B 2
  • (2)
  • Thread B (2)
  • C 3
  • Thread B ( 2, , )

2 3 2 ....

+2

System.out.print , , , IDE

,

+1

. , , , , System.out. , , , .

Volatile does not replace synchronization. It simply warns the compiler that the value can change at any time and, therefore, should appear every time it is referenced, not optimized.

0
source

Source: https://habr.com/ru/post/1524255/


All Articles