Volatile关键字回顾之线程可见性
java中,volatile关键字有两大作用:
1.保证线程的可见性
2.防止指令重排序
这篇文章主要通过典型案例,体现可见性这一特性。
概念:
java中,堆内存是线程共享的。而每个线程,都应该有自己独享的内存用于工作。所以,当线程访问到堆内存中的共享变量时,会考虑copy一份,存在自己的工作空间中。之后对工作空间中的值进行操作,完成后重新写回到堆内存。
这样一来,在多线程同时访问这个变量时,就可能出现拿不到实时的值的问题(根本原因在于:本来共享的变量,因为缓存到各个线程的工作空间导致数据在写回之前不互通)。
而volatile的作用之一,就是解决这一问题。
下面通过一段代码,来展示volatile的这一特性。
public class HelloVolatile {
private volatile boolean running = true; //开关,表示是否可运行
void m(){
System.out.println("m start");
//一直执行
while(running){
}
//如果running一直未true,下面的代码执行不到
System.out.println("m end");
}
public static void main(String[] args) {
HelloVolatile helloVolatile = new HelloVolatile();
//新建线程,run方法调用m方法,running为true时一直循环
new Thread(helloVolatile::m, "非主线程").start();
//休眠1s
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
//主线程设置running为false,如果running不加volatile,则新建的线程是读不到的
helloVolatile.running = false;
}
}
running变量不加volatile的执行结果:
m start
加了volatile的执行结果:
m start
m end
可见性的原理:
MESI(缓存一致性)协议:
1.写数据时,如果发现操作的是共享变量,会发出信号通知其他CPU设置该变量的缓存行为无效状态。
2.当其他CPU使用这个变量时,会先去观察是否有更改的信号,当发现缓存行失效时,会从主内存(堆中)重新读取此变量。
volatile的优缺点:
优点:高效(非锁机制)
缺点:仅仅保证可见性,不保证数据的一致性。
Volatile关键字回顾之线程可见性的更多相关文章
- Volatile 关键字 内存可见性
1.问题引入 实现线程: public class ThreadDemo implements Runnable { private boolean flag = false; @Override p ...
- 全面理解Java内存模型(JMM)及volatile关键字(转载)
关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoad ...
- 全面理解Java内存模型(JMM)及volatile关键字
[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772461 出自[zejian ...
- 并发之volatile关键字
volatile关键字 volatile关键字是什么 在上一章我们讲到了并发的的三个概念,那么今天在讲解下在java中可以保证可见性和有序性的一个关键字. volatile关键字 :当变量的值被该关键 ...
- Java多线程编程——volatile关键字
(本篇主要内容摘自<Java多线程编程核心技术>) volatile关键字的主要作用是保证线程之间变量的可见性. package com.func; public class RunThr ...
- 全面理解Java内存模型(JMM)及volatile关键字(转)
原文地址:全面理解Java内存模型(JMM)及volatile关键字 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型( ...
- 双重检查锁单例模式为什么要用volatile关键字?
前言 从Java内存模型出发,结合并发编程中的原子性.可见性.有序性三个角度分析volatile所起的作用,并从汇编角度大致说了volatile的原理,说明了该关键字的应用场景:在这补充一点,分析下v ...
- 浅析Volatile关键字
浅析Volatile关键字 在java中线程并发中,线程之间通信方式分为两种:共享内存和消息传递.共享内存指的是多个线程之间共享内存的属性状态:消息传递指的是线程之间发送信息来通信.在介绍volati ...
- Java volatile关键字实现原理
场景引入 可见性问题 先来看一张图: 上面的图,是简化版的Java内存模型,一个线程有自己的工作内存,同时还有一个共享的主内存. 线程1和线程2读取数据data时,先从主内存里加载data变量的值到工 ...
随机推荐
- 中文字体压缩器-解决css引入的字体太大的问题
字蛛是一个中文字体压缩器 官方网站:http://font-spider.org/index.html 用于解决页面引入的css字体过大的问题 使用方法: npm i -g font-spider 在 ...
- Intellij IDEA创建 Web 项目
快速构建 Web 项目 打开IDEA,新建Project,左边菜单栏选择 Maven,直接点 Next 选择GroupId和ArtifactId 选择项目名称,默认会填上工程位置.模块姓名等,直接点F ...
- Jenkins+Git+Fastlane+Fir CI集成
上一篇有讲关于fastlane自动化部署,本篇将会着重讲关于fastlane的实际应用. 目标: 利用自动化jenkins打包工具,自动拉取git仓库代码 不需要通过手动检查修改xcode中项目配置修 ...
- 编写一个可复用的SpringBoot应用运维脚本
前提 作为Java开发者,很多场景下会使用SpringBoot开发Web应用,目前微服务主流SpringCloud全家桶也是基于SpringBoot搭建的.SpringBoot应用部署到服务器上,需要 ...
- springmvc两种配置方法
基于配置文件xml方式, 配置springmvc步骤: 1.在pom文件中引入jar包: <!--导入springmvc的jar包--> <dependency> <gr ...
- PhalApi 2.7 开发快速上手
PhalApi是一款国人制作的PHP纯后端框架.它的开发相当简单,同时也具备文档生成等特色功能.下面,我通过简单的几点,让你可以快速入门使用该框架的开发. 建议使用PHPStorm作为IDE,代码提示 ...
- 前端每日实战:42# 视频演示如何用纯 CSS 创作一个均衡器 loader 动画
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/oybWBy 可交互视频教程 此视频 ...
- EventEmitter:从命令式 JavaScript class 到声明函数式的华丽转身
新书终于截稿,今天稍有空闲,为大家奉献一篇关于 JavaScript 语言风格的文章,主角是函数声明式. 灵活的 JavaScript 及其 multiparadigm 相信"函数式&quo ...
- vue项目用sha256、md5、base64加密密码
无论你开发什么样的项目,你可能都会要开发登录.注册.修改密码.忘记密码这些功能,少数项目除外!!要实现这些功能,对于保护用户或者管理员账号密码,这是我们程序员肯定要做的事情.要是用户密码不加密,用明文 ...
- 修改webserver站点用户组权限
例如webserver站点目录为webtest 搭建nginxwebserver服务器的时候,默认的用户和用户组权限为nginx:nginx, 即nginx.conf 和php-frm.conf 中默 ...