美文网首页
volatile java & c++

volatile java & c++

作者: 小雪球的学习笔记 | 来源:发表于2018-05-28 16:19 被阅读0次

    Comparing the volatile keyword in Java, C and C++

    Declaring a volatile variable in Java

    In Java, you can only add the volatile keyword to class members:

    public class MyClass {
       private volatile int count = 0;
       public static volatile int sum = 0;
    }
    

    Arrays can be volatile, but the elements won’t be volatile:

    volatile int[] numbers = new int[10];
    ...
    numbers[0] = 5;  // not volatile
    

    Local variables cannot be volatile:

    public void doStuff() {
       volatile int count = 0; // Error: illegal start of expression
    }
    

    Declaring a volatile variable in C and C++

    In C and C++, the volatile keyword can be applied to local and global variables:

    volatile int globalNumber = 0;
    int* volatile pInt; // volatile pointer to nonvolatile int
    volatile int* volatile pInt2; // volatile pointer to a volatile int
    
    void doStuff() {
       volatile float localNumber = 5.0f;
    }
    

    structs can also have volatile fields:

    struct A {
       volatile double n = 0.0;
    };
    

    In C++, class members can also be volatile:

    class T {
       volatile long id = 0;
    };
    

    In Java, volatile means memory visibility

    When a variable is declared volatile in Java, the compiler is informed that such variable is shared and its value can be changed by another thread. Since the value of a volatile variable can change unexpectedly, the compiler has to make sure its value is propagated predictably to all other threads.

    volatile boolean isDone = false;
    public void run() {
       while (!isDone)
          doWork();
    }
    

    The isDone variable is declared volatile. If that variable is set to true by another thread, this piece of code will read the new value and immediately leave the while-loop. If we forget to add the volatile modifier to that variable, there is a good chance the loop will never finish if the variable is set to true by another thread.

    If a variable is declared volatile, all threads must read its most recent written value.

    In Java, the volatile keyword guarantees memory visibility and it is meant to be used in concurrent programming.
    

    In C/C++, volatile means no optimizations

    -O0 = no optimization
    -O1 = somewhere between -O0 and -O2
    -O2 = Moderate level of optimization, which enables most optimizations
    -O3 = Like -O2 with extra optimizations to reduce code size
    

    You may ask why would someone use this kind of less efficient code. One answer is memory-mapped I/O.

    In C/C++, the volatile keyword is NOT suitable for concurrent programming. It is meant to be used only with special memory (e.g., memory-mapped I/O).
    

    In Java, volatile doesn't guarantee atomicity and thread-safety

    A common misunderstanding about the volatile keyword in Java is whether operations on such variables are atomic or not. The answer to this question can be YES and NO.
    Operations are atomic if you look at individual reads and writes of the volatile variable.

    Operations are NOT atomic if the code has to read the value before updating it.

    volatile int i = 0;
    i += 10;  // not atomic
    
    AtomicInteger i = new AtomicInteger(0);
    i.addAndGet(10);  // atomic
    

    In C/C++, volatile can be used in return types and parameters

    volatile int work(volatile int x) {
      return x + 1;
    }
    

    In C++, volatile can also be used in class methods, constructors and operators

    class MyClass {
      public:
       int normalMethod() { 
          return 1; 
        }
       int volatileMethod() volatile { 
          return 2; 
        }
    };
    

    If an instance of this class is declared volatile, then the code can only call volatile methods on that object:

    int main() {
       volatile MyClass a;
       a.normalMethod();  // error: nonvolatile method cannot be called
       a.volatileMethod();  // OK 
       return 0;
    }
    

    Conclusion

    In Java, volatile variables are meant to be used in multithreaded contexts. Threads that concurrently read a volatile variable will always read its latest value, which means the JVM will not cache the variable internally and its value will be shared across all processors.

    Atomicity and thread-safety in Java are not guaranteed by volatile variables. In summary, you should use the volatile keyword if writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value.

    In C/C++, the volatile keyword is meant to be used with special memory: manipulating I/O registers or memory-mapped hardware. All optimizations on those variables will be disabled, which means that assignments and their order will be preserved. The volatile qualifier doesn’t help us in multithreaded code.

    Java C++
    Purpose Concurrent Programming Special Memory (e.g., memory mapped I/O)
    What difference does it make? Adds visibility to the variable Disables optimizations on the variable
    Is the operation atomic? Yes for individual reads and writes;
    No if the write depends on the current value;
    No
    Applies to class fields local and global variables;
    return types;
    function parameters;
    class fields and methods (C++ only);

    相关文章

      网友评论

          本文标题:volatile java & c++

          本文链接:https://www.haomeiwen.com/subject/toegjftx.html