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. 系列博文-Three.js入门指南(张雯莉)-网格 setInterval方法 requestAnimationFrame方法 使用stat.js记录FPS

    第6章 动画 在本章之前,所有画面都是静止的,本章将介绍如果使用Three.js进行动态画面的渲染.此外,将会介绍一个Three.js作者写的另外一个库,用来观测每秒帧数(FPS). CSS3动画那么 ...

  2. XSS过滤JAVA过滤器filter 防止常见SQL注入

    Java项目中XSS过滤器的使用方法. 简单介绍: XSS : 跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩 ...

  3. Description Resource Path Location Type Cannot change version of project facet Dynamic Web Module to 2.3.

    报错信息:Description Resource Path Location Type Cannot change version of project facet Dynamic Web Modu ...

  4. 菜鸟如何反转到资深Web安全工程师

    90后理工男,计算机专业,毕业于985院校,从事Web安全工作,两年多的时间里先后跳槽3家公司,跳槽理由主要有以下几点:加班多.薪资低.工作内容枯燥,不想安于现状,寄希望于通过跳槽找到一个“钱多.活少 ...

  5. Brown Mood Median Test

    Brown-Mood Median Test 对于两独立样本尺度中的位置参数(中位数)检验问题: \(H_0: med_x = med_y\)   \(H_1=med_x > med_y\) 在 ...

  6. 【.NET异步编程系列1】:await&async语法糖让异步编程如鱼得水

    前导 Asynchronous programming Model(APM)异步编程模型以BeginMethod(...) 和 EndMethod(...)结对出现. IAsyncResult Beg ...

  7. 【重学计算机】操作系统D2章:处理器管理

    1. 指令与处理器模式 指令执行周期:取指.译码.执行 指令分类(根据权限) 特权指令:只能被操作系统内核使用(启动IO,置PC值) 非特权指令:所有程序都能使用 处理器模式: 共有四种:0内核模式, ...

  8. C#字符串的一些常用方法

    字符串常用方法 string str =""; string[] strArray = str.Split('截取字符'); //按字符将字符串拆分为数组 str = str.Re ...

  9. JS点击图片更改照片

    <img src="../../img/20190224185111.png" alt="" id="zhaopian"/> - ...

  10. SQL过滤字符后手工注入漏洞测试(第1题)

    https://www.mozhe.cn/bug/detail/a1diUUZsa3ByMkgrZnpjcWZOYVEyUT09bW96aGUmozhe 分析题目,属于时间盲注,这种情况,通常使用sq ...