对volatile关键字的理解

Posted 老梁讲Java

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对volatile关键字的理解相关的知识,希望对你有一定的参考价值。

本文是基于对 http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 这篇文档的理解

volatile

用volatile修饰的变量,线程在每次使用变量的时候,都会读取主内存也就是堆内存中最新值。

解读下面代码运行结果为什么可能不为1000

public class Counter {
 
    public volatile static int count = 0;
 
    public static void inc() {
 
        //这里延迟1毫秒,使得结果明显
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
        }
 
        count++;
    }
 
    public static void main(String[] args) {
 
        //同时启动1000个线程,去进行i++计算,看看实际结果
 
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Counter.inc();
                }
            }).start();
        }
 
        //这里每次运行的值都有可能不同,可能为1000
        System.out.println("运行结果:Counter.count=" + Counter.count);
    }
}

  如上图,volatile修饰的变量,线程在访问该变量的时候,首先通过引用找到堆内存也就是主内存中的变量值,之后由线程本地内存读取加载该变量,它会建立一个变量副本,此时,原堆内存中变量和这个副本的变量是没有关联关系的,副本中变量经过运算赋值等操作后,会写入或者说同步到主内存,此时count值变了,也就是加了1。但是在多线程环境下,count在load进副本后,在没写入内存之前,又有线程对count变量进行操作,再次加载还有没改变的count值,那么前一个count值同步到主内存和后一个线程操作count值写入内存的值就会相同。

   volatile的几种特性:

  1、原子性

  即一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么全部不执行。volatile无法保证复合操作的原子性

  2、可见性

  指当多个线程访问一个变量的时候,一个线程修改了这个变量的值,其他线程能够立即看到修改的值

  3、有序性

  即程序执行的顺序按照代码的先后顺序执行。

以上是关于对volatile关键字的理解的主要内容,如果未能解决你的问题,请参考以下文章

Volatile关键字理解

深入理解volatile关键字

java并发编程--深入理解volatile关键字

Java编程volatile和transient关键字的理解

全面理解Java内存模型(JMM)及volatile关键字

Java并发多线程编程——volatile关键字