zoukankan      html  css  js  c++  java
  • Java's Volatile Keyword

    转自

    http://tutorials.jenkov.com/java-concurrency/volatile.html

    The Java volatile keyword is used to mark a Java variable as "being stored in main memory". More precisely that means, that every read of a volatile variable will be read from the computer's main memory, and not from the CPU cache, and that every write to a volatile variable will be written to main memory, and not just to the CPU cache.

    Actually, since Java 5 the volatile keyword guarantees more than just that volatile variables are written to and read from main memory. I will explain that in the following sections.

    Java volatile Guarantees Variable Visibility

    The Java volatile keyword guarantees visibility of changes to variables across threads. This may sound a bit abstract, so let me elaborate.

    In a multithreaded application where the threads operate on non-volatile variables, each thread may copy variables from main memory into a CPU cache while working on them, for performance reasons. If your computer contains more than one CPU, each thread may run on a different CPU. That means, that each thread may copy the variables into the CPU cache of different CPUs. This diagram illustrates such a situation:

    With non-volatile variables there are no guarantees about when the Java Virtual Machine (JVM) reads data from main memory into CPU caches, or writes data from CPU caches to main memory. Let me explain what problems that can cause with an example:

    Imagine a situation in which two or more threads have access to a shared object which contains a counter variable declared like this:

    public class SharedObject {
    
        public int counter = 0;
    
    }
    

    Thread 1 could read a shared counter variable with the value 0 into its CPU cache, increment it to 1 and not write the changed value back into main memory. Thread 2 could then read the same countervariable from main memory where the value of the variable is still 0, into its own CPU cache. Thread 2 could then also increment the counter to 1, and also not write it back to main memory. Thread 1 and Thread 2 are now practically out of sync. The real value of the shared counter variable should have been 2, but each of the threads has the value 1 for the variable in their CPU caches, and in main memory the value is still 0. It is a mess! Even if the threads eventually write their value for the sharedcounter variable back to main memory, the value will be wrong.

    By declaring the shared counter variable volatile the JVM guarantees that every read of the variable will always be read from main memory, and that all writes to the variable will always be written back to main memory. Here is how the volatile declaration looks:

    public class SharedObject {
    
        public volatile int counter = 0;
    
    }
    

    In some cases simply declaring a variable volatile may be enough to assure that multiple threads accessing the variable see the latest written value. I will get back to which cases volatile is sufficient later.

    In the situation with the two threads reading and writing the same variable, simply declaring the variable volatile is not enough. Thread 1 may read the counter value 0 into a CPU register in CPU 1. At the same time (or right after) Thread 2 may read the counter value 0 into a CPU register in CPU 2. Both threads have read the value directly from main memory. Now both variables increase the value and writes the value back to main memory. They both increment their register version of counter to 1, and both write the value 1 back to main memory. The value should have been 2 after two increments.

    The problem with multiple threads that do not see the latest value of a variable because that value has not yet been written back to main memory by another thread, is called a "visibility" problem. The updates of one thread are not visible to other threads.

    Since Java 5 the volatile keyword guarantees more than just the reading and writing of a variable from and to main memory.

    And "visibility" problem have been solved.

  • 相关阅读:
    记录一下周末作业
    超链接的 使用和按钮添加
    学习了网页设置上传视频
    Java-JDK安装及环境变量配置
    java-库存管理案例
    java-DateFormat
    java-正则表达式练习
    java-StringBuffer类
    java面对对象-匿名对象
    java static和final关键字
  • 原文地址:https://www.cnblogs.com/lnas01/p/4556006.html
Copyright © 2011-2022 走看看