java内存模型——volatile的可见性 世界速递
volatile的使用与线程安全关系密切,主要作用是使变量在多个线程间可见,另外也有防止指令重排的作用。
比如主内存中有变量a=0,线程1设置a=10,线程2再操作a的时候,是以a=10的基础上进行操作,否则会影响逻辑!
(资料图片)
0 1volatile的可见性
要了解volatile的可见性,首先得了解java内存模型:
java内存模型
Java内存模型由Java虚拟机规范定义,用来屏蔽各个平台的硬件差异。简单来说:
1. 所有变量储存在主内存。
2. 每条线程拥有自己的工作内存,其中保存了主内存中线程使用到的变量的副本。
3. 线程不能直接读写主内存中的变量,所有操作均在工作内存中完成。
线程,主内存,工作内存的交互关系如下图所示
如下列代码所示,rt启动之后修改isRunning的值为false,此时while循环不会停止,因为run方法里得不到改变之后的isRunning。
解决:使用volatile修饰isRunning,这样当isRunning的值改变之后,会立即刷新到主内存里,工作内存也能立即获取到新的值
public class RunThread extends Thread {private boolean isRunning = true; private void setRunning(boolean isRunning){this.isRunning = isRunning; } public void run () {System.out.println("进入run方法"); while(isRunning == true){//... } System.out.println("线程停止"); } public static void main(String[] args) {RunThread rt = new RunThread(); rt.start(); try {Thread.sleep(3000); rt.setRunning(false); System.out.println("isRunning的值已经被设置成false"); Thread.sleep(1000); System.out.println(rt.isRunning); } catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace(); } }}
0 2volatile能防止指令重排
如下列代码所示,这是单例模式的双检锁写法
public class SingletonTest {private volatile static SingletonTest instance = null; private SingletonTest() { } public static SingletonTest getInstance() {if(instance == null) {synchronized (SingletonTest.class){if(instance == null) {instance = new SingletonTest(); //非原子操作 } } } return instance; }}
我们看到instance用了volatile修饰,由于 instance = new SingletonTest();可分解为:
1.memory =allocate(); //分配对象的内存空间2.ctorInstance(memory); //初始化对象3.instance =memory; //设置instance指向刚分配的内存地址
操作2依赖1,但是操作3不依赖2,所以有可能出现1,3,2的顺序,当出现这种顺序的时候,虽然instance不为空,但是对象也有可能没有正确初始化,会出错。
而使用volatile修饰instance之后,不会出现乱序的行为!
0 3volatile不保证原子性以及解决方式
1.什么是原子性?
下列语句中,哪些是原子性操作?
x = 10; //语句1y = x; //语句2x++; //语句3x = x + 1; //语句4
语句1 是直接将数值 10 赋值给 x,也就是说线程执行这个语句的会直接将数值 10 写入到工作内存中;
语句2 实际上包含两个操作,它先要去读取 x 的值,再将 x 的值写入工作内存。虽然,读取 x 的值以及 将 x 的值写入工作内存这两个操作都是原子性操作,但是合起来就不是原子性操作了;
同样的,x++ 和 x = x+1 包括3个操作:读取 x 的值,进行加 1 操作,写入新的值。
只有 语句1 的操作具备原子性。也就是说,只有简单的读取、赋值(而且必须是将数字赋值给某个变量,变量之间的相互赋值不是原子操作)才是原子操作!
2.举例
如下列代码所示,使用volatile修饰的变量count,利用10个线程分别对count进行++操作,而根据上面的表述,++操作不是原子操作!每个线程加1000个数,打印的结果中一定有一个是10000才是对的,但是实际上并不是这样!因为volatile不保证原子性!
public class VolatileNoAtomic extends Thread{private static volatile int count;// private static AtomicInteger count = new AtomicInteger(0); private static void addCount(){for (int i = 0; i < 1000; i++) {count ++;// count.incrementAndGet(); } System.out.println(count); } public void run(){addCount(); } public static void main(String[] args) {VolatileNoAtomic[] arr = new VolatileNoAtomic[10]; for (int i = 0; i < arr.length; i++) {arr[i] = new VolatileNoAtomic(); } for (int i = 0; i < arr.length; i++) {arr[i].start(); } }}
解决:
方法1:使用原子类Atomic类的系列对象,这样既不会阻塞,又能保证原子性!
方法2:使用synchronized修饰addCount方法,这样做的话,线程同步之后会有阻塞,运行时间加长,而且volatile将会失效,不建议这么改
方法3:使用Lock加锁,当然,跟方法2一样的有阻塞
● 架构系列——使用synchronized需要注意什么细节
● 架构系列——线程实现方式以及生命周期的探索
● 架构系列——并发、并行与多线程关系探索
● 架构系列——单体、分布式、集群与冗余的探索
● Java反射:框架设计的灵魂
● 高并发秒杀系统如何设计与优化
● 要准备多少东西去面试---java中高级面试总结(值得收藏)
● 最近的面试有感(7个方面)
● java中的参数传递(只有值传递没有引用传递)
● 38张史上最全的IT工程师技能图谱(高清收藏)
● PLSQL连接本地oracle或远程oracle数据库,实现随意切换(送福利)
● 通过数据泵expdp、impdp方式备份与还原Oracle数据库--值得收藏
● java常见排序算法--选择排序、冒泡排序、插入排序分析与比较
标签:
相关推荐:
最新新闻:
- 4k分辨率是多少?真4k与假4k区别介绍_天天讯息
- 世界即时看!Maven默认的仓库位置在哪里?Maven默认仓库改成自己的仓库步鄹的方法
- java内存模型——volatile的可见性 世界速递
- Zip格式结构图总览 Zip文件结构详解
- 热门看点:商标注册查询入口官网在哪里?商标注册查询入口官网地址及查询方法
- 每日消息!nix系统上加载/管理模块的命令 linux常用命令之module
- mysql-uroot-p命令怎么下载?MySQL数据库安装教程_世界即时看
- 行式数据库系统中的列式存储——Clickhouse-世界热讯
- 表空间用户SQLoracle有啥子优势?详情介绍
- 《碟中谍7:致命清算》海报曝光 阿汤哥再次挑战极限_世界快看
- 天天最新:《街头霸王6》开发者实机演示 “桑吉尔夫 Vs 玛丽莎”
- 什么是BT?BT、FTP、PUB的下载方式有哪些?
- 天天观点:java中BigDecimal的4个造方法 你知道吗?
- 环球微速讯:在阿里巴巴图标库创建自己的工程 并导入第三方图标
- 今日快看!CST怎么用?CST使用心得及使用方法
- word文档中的大括号怎么打?六角括号怎么用键盘打?
- 全球快看:《速度与激情10》新海报发布 终途启程家人一直在身边
- 昆汀准备拍他“最后一部”电影了!今秋开机
- 鱼骨图绘制有什么技巧?3种类型的鱼骨图制作思维导图示例
- 《极乐迪斯科》开发商法律纠纷结束:主创还清欠款-环球新消息
- 全球观天下!PDF怎么编辑?PDF编辑方法大全
- TCP协议详解 一文读懂TCP协议段格式|每日热闻
- cr2是什么格式?CR2格式打开的方法步骤是什么?
- 世界观热点:【科普】什么是NAS?有什么好玩的功能?
- Cydia源是什么?Cydia源添加安装及更新步骤
- UAC功能是什么?关闭UAC功能的操作过程
- 男子称价值1.2万元AJ球鞋被调包 涉事物流:正沟通理赔
- 【干货】Linux管理文件和目录的命令
- 云存储是什么意思?云存储都有哪些用处?
- 牙克石市筑牢医保屏障助力乡村振兴
- 显卡硬件加速有什么用? 开启显卡硬件加速方法
- drivers是什么文件?drivers文件能不能删除?
- 如何卸载迈克菲软件?Mcafee卸载的方法
- PP加速器好用吗?PP加速器安装及使用步骤
- 连接打印机提示“打印处理器不存在”是什么原因?连接打印机提示打印处理器不存在解决步骤
- 变矩器是什么?变速齿轮机构的结构与工作原理
- win10系统怎么使用eZ Flash3刷BIOS?使用EZ Flash3刷BIOS步骤
- win10系统临时文件夹在哪?查找临时文件夹的步骤
- 如何输入avast注册码?avast软件介绍及激活码分享
- LanHelper工具有什么功能?LanHelper工具破解教程
- 笔记本内存条怎么安装?笔记本加内存条安装方法
- 注册表数据怎样进行修改?注册表编辑器打不开有什么解决办法?
- 出现0xc0000005错误是由什么原因造成的?c0000005异常代码解决方法
- Word中省略号怎么打?Word中省略号快捷键
- 耳机有杂音是什么原因造成的?耳机插上还是外放应该怎么办?
- 电脑时间不同步怎么办?电脑时间不同步的解决方法
- 《暗黑破坏神4》终极版预告 6月6日正式发售
- 环球焦点!三人被困雪地 男子用iPhone和大疆无人机成功自救
- 硅谷银行储户排长队取款:中国一公司已取回6亿元
- 苹果MR头显6月见!
- 环球最资讯丨视频神器 LG16:18显示器4099元
- 北京特惠!联想27寸一体机6899元-全球热文
- 大获全胜 网飞获得6座奥斯卡
- 当前快看:《猎天使魔女:起源》IGN 9分:充满童趣和想象力
- 《遇见造物主》首发加入PS+ 4月4日发行
- 《光明旅者:破坏者》抢先体验推迟至秋季
- 昆汀最后一部电影片名曝光 今年秋季开拍_焦点快看
- 旅游零售板块3月14日跌0.25%,中国中免领跌,主力资金净流出8868.52万元_当前热议
- 16mn是什么材质价格多少_16mn是什么材质:环球播报
- COSPLAY图赏:国外小姐姐COS《死或生》玛丽萝丝 女仆装可爱又性感-微资讯
- “张译每剧嘎一个兄弟”上热搜:搭档总会壮烈牺牲
- SE区块链游戏《共生起源》首支预告 有上万角色
- 《最后生还者》第二季不会因游戏差评改剧情 尼尔不在乎那些差评:世界通讯
- 全球快资讯:PS官推“情人节送PS5告白”后续:白色情人节一起玩吗?
- 【环球时快讯】小米万兆路由器现在入手仅1699元:小米路由史上重大升级
- 【天天聚看点】13 代 i9+RTX40 系显卡,ROG 幻 16 翻转屏笔记本开售,miniLED 屏幕
- 焦点日报:美菱智能遥控茶吧机 24 小时保温,258元绝对值
- 【聚看点】冷知识:宠物猫平均寿命已增加到15年
- 《黑暗荣耀2》的蛇是真蛇!李莎拉演员:拍得很开心
- LG发布49GR85DC-B游戏显示器 32:9曲面屏
- 全球今热点:山东岚山区总工会开展心理健康服务活动
- 外网热议:《原神》是否拥有迄今为止最好的开放世界
- 《赛博朋克2077》高清重制MOD:纹理大提升!像新配了眼镜|今日报
- 《生化危机4:重制版》体验版bug:里昂一脚踢飞电锯人|世界热点
- 性价比逆天!i5-1235U迷你主机低至2258元-热资讯