volatile是java虚拟机提供的轻量级的同步机制

JMM(Java内存模型)是围绕着并发编程中原子性、可见性、有序性这三个特征来建立的

原子性:一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行。

可见性:当多个线程同时访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

有序性:程序执行的顺序按照代码的先后顺序执行。

volatile保证了可见性,有序性,不保证原子性

证明可见性的代码:

  1. package concurrent;
  2.  
  3. import java.util.concurrent.TimeUnit;
  4.  
  5. /*
  6. * @description: volatile特性
  7. * @date 2019.04.22 20:48
  8. */
  9. //数据类
  10. class Mydata{
  11.  
  12. volatile int num = 0;
  13.  
  14. public void changeNum(){
  15. this.num = 100;
  16. }
  17. }
  18.  
  19. public class VolatileDemo {
  20.  
  21. public static void main(String[] args) throws InterruptedException{
  22. Mydata mydata = new Mydata();
  23. new Thread(() -> {
  24. System.out.println("===="+Thread.currentThread().getName() +"线程启动===");
  25. //暂停3秒
  26. try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {}
  27. //3秒后t1线程改变num的值
  28. mydata.changeNum();
  29. System.out.println(Thread.currentThread().getName()+"线程将num的值改为"+mydata.num);
  30. },"t1").start();
  31.  
  32. //num的值不变就一直循环
  33. long begin = System.currentTimeMillis();
  34. while (mydata.num == 0){
  35. //num如果不被volatile修饰会一直循环
  36. }
  37. long cost = System.currentTimeMillis() - begin;
  38. System.out.printf(Thread.currentThread().getName()+"线程检测到num的值已经改变,cost{%d},证明了volatile的可见性",cost);
  39. }
  40. }

运行结果为:

  1. ====t1线程启动===
  2. t1线程将num的值改为100
  3. main线程检测到num的值已经改变,cost{3001},证明了volatile的可见性

  

证明不保证原子性的代码:

  1. class Mydata{
  2.  
  3. volatile int num = 0;
  4.  
  5. public void changeNum(){
  6. this.num = 100;
  7. }
  8.  
  9. public void numIncreOne(){
  10. this.num++;
  11. }
  12. }
  13.  
  14. public class VolatileDemo {
  15.  
  16. public static void main(String[] args) throws InterruptedException{
  17.  
  18. Mydata mydata = new Mydata();
  19. //开启10个线程每个线程调用1000次num++
  20. for (int i = 0; i < 10; i++) {
  21. new Thread(() -> {
  22. for (int j = 0; j < 1000; j++) {
  23. mydata.numIncreOne();
  24. }
  25. },String.valueOf(i)).start();
  26. }
  27.  
  28. //输出num的值,如果volatile能保证原子性num将等于10000
  29. System.out.println(mydata.num);
  30. System.out.println(mydata.num ==10000?"volatile可以保证原子性":"volatile无法保证原子性");
  31. }
  32. }

输出结果:

  1. 5856
  2. volatile无法保证原子性

多线程环境中,线程交替执行,编译器会通过对指定进行重排序来进行优化。被volatile修饰的变量不会参与重排序,保证有序性。

证明有序性的代码:

  1. int num = 0;
  2.  
  3. private boolean flag = false;
  4.  
  5. private void reSort1(){
  6. num = 1; //语句1
  7. flag = true; //语句2
  8. }
  9.  
  10. private void reSort2(){
  11. if(flag){
  12. num++;
  13. System.out.println("num的值为"+num);
  14. }
  15. }
  1. 多线程情况下有可能先执行语句2,再执行语句1,从而导致num只自增1次,输出为1

volatile关键字的特性及证明的更多相关文章

  1. volatile关键字的特性总结

    当一个变量定义为volatile后,它将具备两个特性: 1.保证此变量对所有线程的可见性,所谓"可见性",,是指当一个线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的. ...

  2. 你真的了解volatile关键字吗?

    volatile关键字经常在并发编程中使用,其特性是保证可见性以及有序性,但是关于volatile的使用仍然要小心,这需要明白volatile关键字的特性及实现的原理,这也是本篇文章的主要内容. 一. ...

  3. Java面试官最爱问的volatile关键字

    在Java的面试当中,面试官最爱问的就是volatile关键字相关的问题.经过多次面试之后,你是否思考过,为什么他们那么爱问volatile关键字相关的问题?而对于你,如果作为面试官,是否也会考虑采用 ...

  4. 面试中的volatile关键字

    在Java的面试当中,面试官最爱问的就是volatile关键字相关的内容.经过多次面试之后,你是否思考过,为什么他们那么爱问volatile关键字相关的问题?而对于你,如果作为面试官,是否也会考虑采用 ...

  5. JUC 并发编程--05, Volatile关键字特性: 可见性, 不保证原子性,禁止指令重排, 代码证明过程. CAS了解么 , ABA怎么解决, 手写自旋锁和死锁

    问: 了解volatile关键字么? 答: 他是java 的关键字, 保证可见性, 不保证原子性, 禁止指令重排 问: 你说的这三个特性, 能写代码证明么? 答: .... 问: 听说过 CAS么 他 ...

  6. Java单例模式和volatile关键字

    单例模式是最简单的设计模式,实现也非常"简单".一直以为我写没有问题,直到被 Coverity 打脸. 1. 暴露问题 前段时间,有段代码被 Coverity 警告了,简化一下代码 ...

  7. 线程安全(上)--彻底搞懂volatile关键字

    对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好起来却不是一件容易的事.这篇文章将从多个方面来讲解volatile,让你对它更加理解. ...

  8. volatile关键字学习

    volatile关键字在实际工作中我用的比较少,可能因为我并不是造轮子的.但是用的少不是你不掌握的借口,还是要创造场景去使用这个关键字,本文将会提供丰富的demo. volatile 发音:英[ˈvɒ ...

  9. C# volatile 关键字

    volatile 就像大家更熟悉的const一样,volatile是一个类型修饰符(type specifier).它是被设计用来修饰被不同线程访问和修改的变量.如果不加入volatile,基本上会导 ...

随机推荐

  1. Android 5.x Theme 与 ToolBar 实战

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/45303349: 本文出自:[张鸿洋的博客] 1.概述 随着Material D ...

  2. 18.app后端如何实现LBS

    移动互联网,除了一直在线这个特点外,还有一个重要特点,能定位到手机的位置.查找附近的人,附近的餐馆等服务,以及大量的o2o应用, 都需要使用LBS(Location Based Services).那 ...

  3. sort.go

    package clientv3 type SortTarget int type SortOrder int const (     SortNone SortOrder = iota     So ...

  4. 【BZOJ 3626】 [LNOI2014]LCA【在线+主席树+树剖】

    题目链接: TP 题解:   可能是我比较纱布,看不懂题解,只好自己想了…… 先附一个离线版本题解[Ivan] 我们考虑对于询问区间是可以差分的,然而这并没有什么卵用,然后考虑怎么统计答案. 首先LC ...

  5. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

  6. BZOJ_2721_[Violet 5]樱花_数学

    BZOJ_2721_[Violet 5]樱花_数学 Description Input Output $\frac{1}{x}+\frac{1}{y}=\frac{1}{m}$ $xm+ym=xy$ ...

  7. BZOJ_3573_[Hnoi2014]米特运输_树形DP+hash

    BZOJ_3573_[Hnoi2014]米特运输_树形DP+hash 题意: 给你一棵树每个点有一个权值,要求修改最少的权值,使得每个节点的权值等于其儿子的权值和且儿子的权值都相等. 分析: 首先我们 ...

  8. React组件设计

    React组件设计 组件分类 展示组件和容器组件 展示组件 容器组件 关注事物的展示 关注事物如何工作 可能包含展示和容器组件,并且一般会有DOM标签和css样式 可能包含展示和容器组件,并且不会有D ...

  9. 卸载office密钥的命令

    1,管理员运行CMD或者PowerShell2,转到2016安装目录,C:\Program Files\Microsoft Office\Office16,这是64位的,32位的在C:\Program ...

  10. 腾讯面试:一条SQL语句执行得很慢的原因有哪些?---不看后悔系列

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...