What is the volatile keyword useful for?

前端 未结 23 2607
闹比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 05:51

    Absolutely, yes. (And not just in Java, but also in C#.) There are times when you need to get or set a value that is guaranteed to be an atomic operation on your given platform, an int or boolean, for example, but do not require the overhead of thread locking. The volatile keyword allows you to ensure that when you read the value that you get the current value and not a cached value that was just made obsolete by a write on another thread.

    0 讨论(0)
  • 2020-11-21 05:52

    volatile is very useful to stop threads.

    Not that you should be writing your own threads, Java 1.6 has a lot of nice thread pools. But if you are sure you need a thread, you'll need to know how to stop it.

    The pattern I use for threads is:

    public class Foo extends Thread {
    
      private volatile boolean close = false;
    
      public void run() {
        while(!close) {
          // do work
        }
      }
      public void close() {
        close = true;
        // interrupt here if needed
      }
    }
    

    In the above code segment, the thread reading close in the while loop is different from the one that calls close(). Without volatile, the thread running the loop may never see the change to close.

    Notice how there's no need for synchronization

    0 讨论(0)
  • 2020-11-21 05:56

    One common example for using volatile is to use a volatile boolean variable as a flag to terminate a thread. If you've started a thread, and you want to be able to safely interrupt it from a different thread, you can have the thread periodically check a flag. To stop it, set the flag to true. By making the flag volatile, you can ensure that the thread that is checking it will see it has been set the next time it checks it without having to even use a synchronized block.

    0 讨论(0)
  • 2020-11-21 05:56

    A variable declared with volatile keyword, has two main qualities which make it special.

    1. If we have a volatile variable, it cannot be cached into the computer's(microprocessor) cache memory by any thread. Access always happened from main memory.

    2. If there is a write operation going on a volatile variable, and suddenly a read operation is requested, it is guaranteed that the write operation will be finished prior to the read operation.

    Two above qualities deduce that

    • All the threads reading a volatile variable will definitely read the latest value. Because no cached value can pollute it. And also the read request will be granted only after the completion of the current write operation.

    And on the other hand,

    • If we further investigate the #2 that I have mentioned, we can see that volatile keyword is an ideal way to maintain a shared variable which has 'n' number of reader threads and only one writer thread to access it. Once we add the volatile keyword, it is done. No any other overhead about thread safety.

    Conversly,

    We can't make use of volatile keyword solely, to satisfy a shared variable which has more than one writer thread accessing it.

    0 讨论(0)
  • 2020-11-21 05:57

    volatile has semantics for memory visibility. Basically, the value of a volatile field becomes visible to all readers (other threads in particular) after a write operation completes on it. Without volatile, readers could see some non-updated value.

    To answer your question: Yes, I use a volatile variable to control whether some code continues a loop. The loop tests the volatile value and continues if it is true. The condition can be set to false by calling a "stop" method. The loop sees false and terminates when it tests the value after the stop method completes execution.

    The book "Java Concurrency in Practice," which I highly recommend, gives a good explanation of volatile. This book is written by the same person who wrote the IBM article that is referenced in the question (in fact, he cites his book at the bottom of that article). My use of volatile is what his article calls the "pattern 1 status flag."

    If you want to learn more about how volatile works under the hood, read up on the Java memory model. If you want to go beyond that level, check out a good computer architecture book like Hennessy & Patterson and read about cache coherence and cache consistency.

    0 讨论(0)
  • 2020-11-21 05:57

    There are two different uses of volatile keyword.

    1. Prevents JVM from reading values from register (assume as cache), and forces its value to be read from memory.
    2. Reduces the risk of memory in-consistency errors.

    Prevents JVM from reading values in register, and forces its value to be read from memory.

    A busy flag is used to prevent a thread from continuing while the device is busy and the flag is not protected by a lock:

    while (busy) {
        /* do something else */
    }
    

    The testing thread will continue when another thread turns off the busy flag:

    busy = 0;
    

    However, since busy is accessed frequently in the testing thread, the JVM may optimize the test by placing the value of busy in a register, then test the contents of the register without reading the value of busy in memory before every test. The testing thread would never see busy change and the other thread would only change the value of busy in memory, resulting in deadlock. Declaring the busy flag as volatile forces its value to be read before each test.

    Reduces the risk of memory consistency errors.

    Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a "happens-before" relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads.

    The technique of reading, writing without memory consistency errors is called atomic action.

    An atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete.

    Below are actions you can specify that are atomic:

    • Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
    • Reads and writes are atomic for all variables declared volatile (including long and double variables).

    Cheers!

    0 讨论(0)
提交回复
热议问题