为什么80%的码农都做不了架构师?>>>   

什么是volatile关键字

volatile 关键字在多线程程序中起着很重要的作用。当多个线程操作同一个变量时,每个线程将拥有对那个变量的本地缓存拷贝,因此,当某一个线程修改了这个变量的值时,实际上修改的是它本地缓存中的变量值,而不是主内存中的变量值,操作这个变量的其他线程并不知道这个变量的值被改变了。为了避免这种情况,我们可以用 valatile 关键字声明这个变量,用 valatile 声明了这个变量之后,变量将不在本地缓存中保存,而在主内存中保存,当有线程修改了它的值以后,它的更新值将被更新到主内存当中,随后,其他线程也能访问更新后的值。当一个变量被声明为 volatile 后,java 内存模型确保所有使用该变量的线程能看到相同的、一致的值。

volatile关键字使用

首先,创建 VolatileData 类,代码如下:

public class VolatileData {//声明为volatile类型private volatile int counter = 0;/*** 返回counter变量的值* @return*/public int getCounter() {return counter;}/*** 自增counter变量的值*/public void increaseCounter() {++counter;}
}

接下来创建 VolatileThread 类,代码如下:

public class VolatileThread extends Thread {private final VolatileData volatileData;public VolatileThread(VolatileData volatileData) {this.volatileData = volatileData;}/*** 调用VolatileData类中的两个方法,进行取值和自增操作*/@Overridepublic void run() {int oldValue = volatileData.getCounter();System.out.println("[Thread " + Thread.currentThread().getId() + "]: Old value = " + oldValue);volatileData.increaseCounter();int newValue = volatileData.getCounter();System.out.println("[Thread " + Thread.currentThread().getId() + "]: New value = " + newValue);}}

最后,创建 VolatileMain 类,对以上程序进行测试,代码如下:

public class VolatileMain {private final static int TOTAL_THREADS = 2;public static void main(String[] args) throws InterruptedException {VolatileData volatileData = new VolatileData();Thread[] threads = new Thread[TOTAL_THREADS];for(int i = 0; i < TOTAL_THREADS; ++i)threads[i] = new VolatileThread(volatileData);//开始读取变量值的操作for(int i = 0; i < TOTAL_THREADS; ++i)threads[i].start();//等待所有线程操作终止for(int i = 0; i < TOTAL_THREADS; ++i)threads[i].join();}
}

在 VolatileMain 类中,使用了两个线程来访问 volatile 变量,输出如下:

[Thread 10]: Old value = 0
[Thread 11]: Old value = 0
[Thread 10]: New value = 1
[Thread 11]: New value = 2

从输出可以看到,首先,两个线程都输出了相同的值,接着,在 increaseCounter 方法被调用之后,两个线程都访问和输出了最新的 volatile 变量的值。

happens-before 关系

在使用 volatile 关键字时,不得不提一下 java 内存模型的 happens-before 关系。happens-before 关系是 java 内存模型的一个重要方面。它建立在两个不同的事件之间,使第一个事件对对象的所有改变都可以被第二个事件看到和反映出。比如当一个线程对 volatile 变量进行写操作后,另一个线程随后访问该变量,happens-before 关系就建立了。因此,所有对 volatile 变量的改变对其他线程来说是可见的。

需要注意的

当在程序中使用 volatile 关键字时,我们必须注意以下几点:

  • volatile 关键字并不能消除原子之间的同步操作的需要,因为内存一致性错误仍然是可能的

  • 使用原子变量比使用 synchronized 同步代码更有效率,但是为了避免内存一致性错误,需要作出额外的努力

  • volatile 关键字不能替代 synchronized 同步代码块和方法

转载于:https://my.oschina.net/dabird/blog/904430

volatile关键字使用总结相关推荐

  1. java中实现具有传递性吗_Java中volatile关键字详解,jvm内存模型,原子性、可见性、有序性...

    一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...

  2. volatile关键字之全面深度剖析

    引言 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字 ...

  3. c语言中volatile关键字的作用

    读文章之前 可以先看一下<程序员的自我修养 >第28页 过度优化. volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直 ...

  4. C语言volatile关键字详解

    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...

  5. 爆赞,对 volatile 关键字讲解最好的一篇文章!

    欢迎关注方志朋的博客,回复"666"获面试宝典 最近,在一篇文章中了解到了 volatile 关键字,在强烈的求知欲趋使下,我查阅了一些相关资料进行了学习,并将学习笔记记录如下,希 ...

  6. Java并发编程:JMM和volatile关键字

    Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内置高速缓存区.高速缓存区的加入使得CP ...

  7. c#中volatile关键字的作用

    恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1;  ...

  8. 26张图带你彻底搞懂volatile关键字

    引子 小艾吃饭路上碰上小牛,忙问:你昨天面大厂面的咋样了?听说他们最喜欢问多线程相关知识. 小牛说:对啊,第一个问题我就讲了20分钟,直接把面试官讲服了. 小艾忙问:什么问题能讲这么久?是不是问你情感 ...

  9. C++中的volatile关键字

    1.使用 volatile int i = 10; 2.使用volatile时要几个注意的点: volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素(操作系统.硬 ...

  10. volatile关键字的作用、原理

    在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...

最新文章

  1. matlab 三维矩阵向量化,Matlab:向量化三维矩阵的工艺
  2. tomcat和idea都占用了8080_IDEA 启动tomcat 端口占用原因以及解决方法( 使用debug模式)...
  3. 合并工具_分享一个SM to HISM合并工具
  4. PHP一个比较完善的树形结构代码
  5. 图解TCP三次握手和四次挥手!(简单易懂)
  6. 前端开发书籍推荐与学习路线
  7. 企业要想迅速壮大,不仅需要大量的人才
  8. linux内核计算次方,linux内核中的循环缓冲去的设计与实现
  9. PHP中普通类、抽象类、接口之间的关联
  10. 正态分布里的西格玛_七大数据陷阱之油腻的统计学:正态分布来了
  11. pycharm搭建第一个django项目
  12. centos内存压力测试软件,教你在CentOS下的CPU、内存、IO、网络的压力测试工具与方法...
  13. STM32入门指南(0)—配置开发环境
  14. 对10G/40Gphy中auto-negotiation功能调试
  15. linux443端口无法建立连接,无法通过端口443连接到ssh
  16. 基于python学生档案管理系统的设计与实现.rar(毕业论文+程序源码+答辩PPT)
  17. Clojure基础语法学习笔记(一)
  18. Intel第十代CPU集成显卡不再支持 Legacy启动 (i5-10400...)
  19. padding的用途
  20. html居中小圆点点怎么打出来,目录的点怎么打 WORD目录里的点点怎么打

热门文章

  1. linux 下的挂载
  2. 吴恩达CS 230深度学习课开学了!秋季视频全部上线,课件小抄应有尽有
  3. 库克终于承认:苹果滞销因iPhone价高,连累财报即将降价促销
  4. 语音合成论文和英伟达撞车,韩国小哥紧急放出全部草稿代码和样本 | 资源帖...
  5. 亚马逊狂发智能硬件新品:全新音箱、微波炉、挂钟、家庭卫士
  6. 蔚来汽车提交IPO招股书:三年亏百亿,腾讯为大股东
  7. “小心!有人在偷看你手机!”谷歌搞了个被偷窥提醒算法
  8. 密码学是如何保护区块链的 1
  9. Shell脚本批量清除Nginx缓存
  10. pushViewController自定义动画http://blog.csdn.net/ralbatr/article/details/22039233