A
A
Anatoly2018-07-12 10:30:17
Java
Anatoly, 2018-07-12 10:30:17

Why does this code throw RuntimeException despite volatile?

I am learning multithreading in Java. As far as I understand, JMM has a guarantee that after writing to volitile, all operations must be completed before. Those. if when reading in another thread y is 2, then x must be 1. But this does not happen. CHADNT?

public class Reordering {
    int x = 0;
    volatile int y = 0;

    public void writer() {
        x = 1;
        y = 2;
    }

    public void reader() {

        if (y == 2) {
            if(x == 0) {
                throw new RuntimeException();
            }

            this.x = 0;
            this.y = 0;
        }
    }

    public static void main(String[] args) {
        final Reordering reordering = new Reordering();

        final Thread thread = new Thread(() -> {
            while (true) {
                reordering.writer();
            }
        });

        thread.setDaemon(true);
        thread.start();

        while (true) {
            reordering.reader();
        }
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Gornostaev, 2018-07-12
@codefucker

The happens-before guarantee does not exclude racing

reader     writer  состояние
---------- ------ ------------
перед x=0          x=1, y=2
             x=1   x=1, y=2
x=0                x=0, y=2
y=0                x=0, y=0
             y=2   x=0, y=2

The next time it is called reader, it will get the state in which xis 0 when it yis 2.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question