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

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

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

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

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

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

证明可见性的代码:

 package concurrent;

 import java.util.concurrent.TimeUnit;

 /*
* @description: volatile特性
* @date 2019.04.22 20:48
*/
//数据类
class Mydata{ volatile int num = 0; public void changeNum(){
this.num = 100;
}
} public class VolatileDemo { public static void main(String[] args) throws InterruptedException{
Mydata mydata = new Mydata();
new Thread(() -> {
System.out.println("===="+Thread.currentThread().getName() +"线程启动===");
//暂停3秒
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {}
//3秒后t1线程改变num的值
mydata.changeNum();
System.out.println(Thread.currentThread().getName()+"线程将num的值改为"+mydata.num);
},"t1").start(); //num的值不变就一直循环
long begin = System.currentTimeMillis();
while (mydata.num == 0){
//num如果不被volatile修饰会一直循环
}
long cost = System.currentTimeMillis() - begin;
System.out.printf(Thread.currentThread().getName()+"线程检测到num的值已经改变,cost{%d},证明了volatile的可见性",cost);
}
}

运行结果为:

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

  

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

class Mydata{

    volatile int num = 0;

    public void changeNum(){
this.num = 100;
} public void numIncreOne(){
this.num++;
}
} public class VolatileDemo { public static void main(String[] args) throws InterruptedException{ Mydata mydata = new Mydata();
//开启10个线程每个线程调用1000次num++
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
mydata.numIncreOne();
}
},String.valueOf(i)).start();
} //输出num的值,如果volatile能保证原子性num将等于10000
System.out.println(mydata.num);
System.out.println(mydata.num ==10000?"volatile可以保证原子性":"volatile无法保证原子性");
}
}

输出结果:

5856
volatile无法保证原子性

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

证明有序性的代码:

     int num = 0;

     private boolean flag = false;

     private void reSort1(){
num = 1; //语句1
flag = true; //语句2
} private void reSort2(){
if(flag){
num++;
System.out.println("num的值为"+num);
}
}
多线程情况下有可能先执行语句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. How nginx "location if" works

    Nginx's if directive does have some weirdness in practice. And people may misuse it when they do not ...

  2. ASP.NET CORE Linux发布工具(文件对比 只上传差异文件;自动启停WebServer命令;上传完成自动预热WebServer)

    最近这几日在搞一个小网站:教你啊 :(感兴趣的朋友可以来捧场,在这个网站上有任何消费我都可以退还) 由于更新频繁,手动更新特别麻烦,于是开发了这个小工具 用了一段时间,还是挺顺手的,同时.NET Co ...

  3. CentOS6.*安装gitolite

    http://www.kankanews.com/ICkengine/archives/64748.shtml 2人收藏此文章, 发表于4小时前(2013-10-22 16:12) , 已有26次阅读 ...

  4. 干货 | Java中获取类名的3种方法!

    获取类名的方法 Java 中获取类名的方式主要有以下三种. getName() 返回的是虚拟机里面的class的类名表现形式. getCanonicalName() 返回的是更容易理解的类名表示. g ...

  5. selenium相关技术研究(从1.0-3.0)

    注: 以下内容引自http://www.cnblogs.com/hhudaqiang/p/6550135.html Selenium相关技术研究(从1.0-3.0) 好吧,最近看wxpython有点多 ...

  6. ConcurrentLinkedQueue简介

    ConcurrentLinkedQueue是一个基于链表的无界线程安全队列,非阻塞实现方式,先进先出,适合高并发的场景. 非阻塞的性能较好,采用CAS,避免加锁的时间,保证数据一致性. 采用" ...

  7. [Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086

    额... 首先,看到这道题,第一想法就是二分答案+线段树... 兴高采烈的认为我一定能AC,之后发现n是500000... nlog^2=80%,亲测可过... 由于答案是求满足题意的最大长度-最小长 ...

  8. WAMP下配置FCGID+ZendGuardLoader

    公司的项目里,有几个文件是被加密的,经过一翻折腾,终于配置成功 文件加密技术用的是ZendGuard,所以必须安装的PHP必须得是nts的 一.下载并配置PHP 先下载安装php,注意VC版本和是否n ...

  9. 【爆料】-《堪培拉大学毕业证书》Canberra一模一样原件

    ☞堪培拉大学毕业证书[微/Q:2544033233◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归& ...

  10. appium----【已解决】【Mac】安装sudo npm install -g appium-doctor总是提示“Error: EACCES: permission denied........”

    [mac电脑] 问题: (1)npm install -g appium-doctor    (2)sudo npm install -g appium-doctor (3)cnpm install ...