一、前言

volatile的关键词的使用在JVM内存模型中已是老生常谈了,这篇文章主要结合自己对可见性的一些认识和一些直观的例子来谈谈volatile。文章正文大致分为三部分,首先会介绍一下happen-before,接着讲解volatile的一些使用场景,最后会附上一些例子来论证使用与不使用volatile的区别。
二、happen-before
对操作系统有认识的同学一定知道,CPU一般有三级缓存,在与内存交互的时候,存在缓存与内存的更新问题,其次CPU在读取指令的时候,会做一些指令重排序的工作,提高程序运行效率。类比JVM内存模型(见下图),每个线程拥有自己的工作内存,同时存在一个主存,线程间通过主存来进行通信,同样的,JVM也存在指令重排序,可见JVM内存模型与实际物理内存模型十分相似。(这里顺便提一下,编译器其实也会作一定重排序优化)。
作为开发人员,你不可能了解到每个JVM优化细节,更不可能了解到CPU何时会进行指令重排序,所以java语言定义了更上层的一个概念,就是"happen-before"。起初,我看到这个单词的时候,误以为这是一个指令执行顺序的规则,后来仔细想想又发觉不对劲。如果”happen-before“仅仅是抽象了指令执行顺序的概念,那么它就把握不了“工作内存将值写回主存”和“工作内存从主存中刷新自己的值”这个两个action的时机。那么这个概念也就变得没什么意义了。所以!所以!所以!”happen-before“是一个可见性的原则!!!
下面给出happen-before的具体规则:
程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作;
锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作;
volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作;
传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C;
线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作;
线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生;
线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行;
对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始;
三、volatile的使用场景
happen-before的第三条规则提到“volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作”,也就是说;一个volatile变量的写操作对后续对读操作可见。说白了就是每次写完volatile变量,都会将值从工作内存写回到主存中去,每次读取volatile变量,工作内存必须从主存中刷新下自己的值。如此的话,volatile就是为了解决多个线程共享数据的可见性问题。但是不是任何数据共享场景都可以使用volatile,必须满足以下两种情景才行。
应用场景:
1.多个线程不依赖原值的情况下进行读写操作
2.一个线程依赖原值进行写操作,多个线程进行读操作
在我看来,除了这两种情况外,无非是多个线程依赖原值进行运算,这样子倒不是说volatile可见性不起作用了,而是无法保证读取原值和运算是一个原子操作!举个简单的例子,多个线程执行i++;i是一个共享变量,由于读取i的值和i自增不是一个原子操作,所以i最终会丢失掉一部分自增过程。代码如下,最终i输出的结果是一个小于1000的整数。
/**
* Created by chenqimiao on 17/8/23.
*/
public class Testv {
public static volatile int i = 0;
public static void main(String args[]){
for (int i =0;i<1000;i++){
new Thread(){
public void run(){
Thread.yield();
Testv.i++;
}
}.start();
}
System.out.println(Testv.i);
}
}
要满足以上这种需求,我们还必须赋予代码原子性,最常用的肯定是锁操作了,一个字稳,性能可观,同时保证原子性和可见性。如果想操作一波的话,还可以考虑使用一些无锁操作,如CAS,象java.util.concurrent包下的一些原子类就是利用了CAS来做到原子性,但原子性并不能保证可见性,这个时候,还需要配合volatile。
以上种种都是对volatile使用场景的概括,想了解具体的使用场景可以参考博文:https://www.ibm.com/developerworks/cn/java/j-jtp06197.html
四、volatile可见性的证明
先上段代码好了,不知道从何说起了。
package com.example.demo.netty;
/**
* Created with IntelliJ IDEA.
* User: chenqimiao
* Date: 2017/8/23
* Time: 9:16
* To change this template use File | Settings | File Templates.
*/
public class VolatileTest {
boolean isStop = false;
public void test(){
Thread t1 = new Thread(){
public void run() {
isStop=true;
}
};
Thread t2 = new Thread(){
public void run() {
while (!isStop);
}
};
t2.start();
t1.start();
}
public static void main(String args[]) throws InterruptedException {
for (int i =0;i<25;i++){
new VolatileTest().test();
}
}
}
上面这段代码可能永远也不会结束,因为线程一对isStop的赋值,线程二可能对此并不可见。当然只是可能,所以为了放大可见性问题,我这里作了25次循环。只要有一组线程,“线程一对isStop的赋值,线程二对此不可见”的情况发生,就不会退出程序。
now,假如你给 isStop 添加一个 volatile 关键字,那么你会发现程序立马就会退出。
总结
以上所述是小编给大家介绍的volatile可见性的一些认识和论证,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# volatile
# 可见性
# java
# java并发编程关键字volatile保证可见性不保证原子性详解
# Java并发volatile可见性的验证实现
# 通过volatile验证线程之间的可见性
# Java并发编程-volatile可见性详解
# volatile保证可见性及重排序方法
# 关键词
# 多个
# 是一个
# 自己的
# 见性
# 原值
# 作了
# 小编
# 性问题
# 检测到
# 都是
# 对此
# 就会
# 好了
# 也会
# 还可以
# 也就
# 子类
# 在此
# 老生常谈
相关文章:
ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?
三星网站视频制作教程下载,三星w23网页如何全屏?
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
建站之星代理平台如何选择最佳方案?
,怎么在广州志愿者网站注册?
股票网站制作软件,网上股票怎么开户?
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
建站之星如何实现PC+手机+微信网站五合一建站?
名字制作网站免费,所有小说网站的名字?
如何高效生成建站之星成品网站源码?
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
建站之星在线客服如何快速接入解答?
如何快速上传建站程序避免常见错误?
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
再谈Python中的字符串与字符编码(推荐)
如何在Windows环境下新建FTP站点并设置权限?
nginx修改上传文件大小限制的方法
Python多线程使用规范_线程安全解析【教程】
网站专业制作公司,网站编辑是做什么的?好做吗?工作前景如何?
如何在Golang中使用replace替换模块_指定本地或远程路径
,柠檬视频怎样兑换vip?
如何快速生成高效建站系统源代码?
如何在阿里云虚拟服务器快速搭建网站?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
c# 在高并发场景下,委托和接口调用的性能对比
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
网站制作模板下载什么软件,ppt模板免费下载网站?
如何在景安服务器上快速搭建个人网站?
建站之星CMS建站配置指南:模板选择与SEO优化技巧
孙琪峥织梦建站教程如何优化数据库安全?
如何基于云服务器快速搭建网站及云盘系统?
淘宝制作网站有哪些,淘宝网官网主页?
如何彻底卸载建站之星软件?
外汇网站制作流程,如何在工商银行网站上做外汇买卖?
如何优化Golang Web性能_Golang HTTP服务器性能提升方法
PHP正则匹配日期和时间(时间戳转换)的实例代码
建站之星如何配置系统实现高效建站?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
外贸公司网站制作哪家好,maersk船公司官网?
高防服务器租用如何选择配置与防御等级?
湖北网站制作公司有哪些,湖北清能集团官网?
如何在Golang中引入测试模块_Golang测试包导入与使用实践
,怎么用自己头像做动态表情包?
如何用VPS主机快速搭建个人网站?
家具网站制作软件,家具厂怎么跑业务?
临沂网站制作公司有哪些,临沂第四中学官网?
早安海报制作网站推荐大全,企业早安海报怎么每天更换?
文字头像制作网站推荐软件,醒图能自动配文字吗?
专业网站建设制作报价,网页设计制作要考什么证?
*请认真填写需求信息,我们会在24小时内与您取得联系。