前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >对volatile关键字的理解

对volatile关键字的理解

作者头像
老梁
发布2019-09-10 16:34:08
3480
发布2019-09-10 16:34:08
举报

本文是基于对 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、有序性

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-03-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档