简体   繁体   中英

Java concurrency

I have the following question: why in this case the second thread see when the first thread changes the value of number:

public static void main(String[] args) throws InterruptedException {

    Temp t = new Temp();
    t.go();
}

static class Temp {
    int number = 2;

    public void go() {

        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                number = 100;
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    System.out.println(number);
                }
            }
        }).start();
    }
}

I expected number value to be cached from the second thread and when the first thread change it, the second thread will be "uninformed" for that and it will print always 2 ! But in practice when the first thread changed the number variable the second thread see this change and start printing 100. Why is that ? I know that it is not 100% sure that the second thread will cache the variable, but in most cases it does this. I thing that I am missing somethig important. Thanks in advance.

According to the Java Memory Model it's not guaranteed that the value changed by one thread will be visible from another. However it does not say the opposite: it can be visible. It's up to the implementation of virtual machine and your hardware. If it's visible today on your CPU with your VM it does not mean that it will be visible always on every hardware and every virtual machine. You just cannot rely on this.

If you still want to see the effect, you can replace the second thread code with the following one:

new Thread(new Runnable() {

    @Override
    public void run() {
        while (number < 100) {
        }
        System.out.println(number);
    }
}).start();

This produces stable result on HotSpot virtual machine: your program never ends (though adding a volatile keyword on number field will make it ending in 5 seconds). Of course you cannot rely on this either.

This is what is known as "shared memory".

The variable "number" is in memory shared by both threads (heap), not on each thread stack.

That's why changing it in one thread reflects on the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM