What is the volatile keyword useful for?

前端 未结 23 2496
闹比i
闹比i 2020-11-21 05:32

At work today, I came across the volatile keyword in Java. Not being very familiar with it, I found this explanation.

Given the detail in which that arti

23条回答
  •  有刺的猬
    2020-11-21 06:15

    While I see many good Theoretical explanations in the answers mentioned here, I am adding a practical example with an explanation here:

    1.

    CODE RUN WITHOUT VOLATILE USE

    public class VisibilityDemonstration {
    
    private static int sCount = 0;
    
    public static void main(String[] args) {
        new Consumer().start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            return;
        }
        new Producer().start();
    }
    
    static class Consumer extends Thread {
        @Override
        public void run() {
            int localValue = -1;
            while (true) {
                if (localValue != sCount) {
                    System.out.println("Consumer: detected count change " + sCount);
                    localValue = sCount;
                }
                if (sCount >= 5) {
                    break;
                }
            }
            System.out.println("Consumer: terminating");
        }
    }
    
    static class Producer extends Thread {
        @Override
        public void run() {
            while (sCount < 5) {
                int localValue = sCount;
                localValue++;
                System.out.println("Producer: incrementing count to " + localValue);
                sCount = localValue;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    return;
                }
            }
            System.out.println("Producer: terminating");
        }
    }
    }
    

    In the above code, there are two threads - Producer and Consumer.

    The producer thread iterates over the loop 5 times (with a sleep of 1000 milliSecond or 1 Sec) in between. In every iteration, the producer thread increases the value of sCount variable by 1. So, the producer changes the value of sCount from 0 to 5 in all iterations

    The consumer thread is in a constant loop and print whenever the value of sCount changes until the value reaches 5 where it ends.

    Both the loops are started at the same time. So both the producer and consumer should print the value of sCount 5 times.

    OUTPUT

    Consumer: detected count change 0
    Producer: incrementing count to 1
    Producer: incrementing count to 2
    Producer: incrementing count to 3
    Producer: incrementing count to 4
    Producer: incrementing count to 5
    Producer: terminating
    

    ANALYSIS

    In the above program, when the producer thread updates the value of sCount, it does update the value of the variable in the main memory(memory from where every thread is going to initially read the value of variable). But the consumer thread reads the value of sCount only the first time from this main memory and then caches the value of that variable inside its own memory. So, even if the value of original sCount in main memory has been updated by the producer thread, the consumer thread is reading from its cached value which is not updated. This is called VISIBILITY PROBLEM .

    2.

    CODE RUN WITH VOLATILE USE

    In the above code, replace the line of code where sCount is declared by the following :

    private volatile  static int sCount = 0;
    

    OUTPUT

    Consumer: detected count change 0
    Producer: incrementing count to 1
    Consumer: detected count change 1
    Producer: incrementing count to 2
    Consumer: detected count change 2
    Producer: incrementing count to 3
    Consumer: detected count change 3
    Producer: incrementing count to 4
    Consumer: detected count change 4
    Producer: incrementing count to 5
    Consumer: detected count change 5
    Consumer: terminating
    Producer: terminating
    

    ANALYSIS

    When we declare a variable volatile, it means that all reads and all writes to this variable or from this variable will go directly into the main memory. The values of these variables will never be cached.

    As the value of the sCount variable is never cached by any thread, the consumer always reads the original value of sCount from the main memory(where it is being updated by producer thread). So, In this case the output is correct where both the threads prints the different values of sCount 5 times.

    In this way, the volatile keyword solves the VISIBILITY PROBLEM .

提交回复
热议问题