前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java Concurrent volatile

Java Concurrent volatile

作者头像
邹志全
发布2019-07-31 10:55:12
3720
发布2019-07-31 10:55:12
举报
文章被收录于专栏:EffectiveCodingEffectiveCoding

基础概念

volatile 是一个Java 中的关键字,一个提供基础同步属性的关键字。针对JVM重排序在并发场景下的问题,被vlolatile修饰的关键词,编译器不会将该变量的操作与其他内存操作进行重排序。

1、重排序:如果熟悉JVM的话,应该就很清楚Java的重排序了。重排序主要分为:编译器优化的重排序、指令级别并行的重排序、内存系统的重排序。其中编译器重排序:在不改变代码语义的情况下,优化性能而改变了代码执行顺序。指令并行的重排序:处理器采用并行技术使多条指令重叠执行,在不存在数据依赖的情况下,改变机器指令的执行顺序。内存系统的重排序:使用缓存和读写缓冲区时,加载和存储可能是乱序执行。 2、JMM:java 内存模型(一种语言级别的内存模型),Java内存模型分为一个工作线程、线程私有的工作内存、共享的主存。

image.png

3、as-if-serial:无论怎么排,要保证和串行执行的结果一致。对于单线程来说,对存在依赖关系的操作进行重排序,不会改变最后的执行结果,在多线程程序中,对存在依赖关系的操作进行重排序,可能会改变最后的执行结果。就需要我们自己来保证as-if-serial了。 4、hanpens-before:指前一个操作对后一个操作可见。(注意一点:不是前一个操作必须在后一个操作之前执行,不是串行执行) 看完这三个前提,就可以去理解volatile了,

volatile原理

volatile更像是语言层面,对于JVM执行过程中对于重排序的限制,是一种内存屏障,这个屏障就像是一堵墙,阻止了前后的重排序操作(具体屏障:LoadLoad屏障和LoadStore屏障)

image.png

StoreStore、StoreLoad

image.png

volatile 保证了一种可见性,什么意思呢,就是说volatile修饰的变量,产生变化时,立马写入主存。保证其他线程能发现其变化,保证了正确性,也就是happens-before。

常见问题

1、volatile不是锁,仅仅是一种程序执行过程中的指令级的同步策略,保证了可见性、避免重排序 2、volatile能够维持被修饰变量单个的原子操作。所以说,对于volatile double 进行单个写操作在多线程并发环境下是完全正常的。这里注意一点,一定是单个操作,像是i++; i--;之类的这明显是复合操作哈,别较真当作单个操作。

使用场景

1、保证long、double等的单个操作的原子性,不至于写完一半被读走。 2、作为基础信号量,发生变化时,能够其他线程周知,但记住一点复合操作可不保证原子性,读后写什么的在多线程并发环境下还是进行同步操作吧。 volatile 差不多就这些,真正的使用体验可以尝试自己写demo,比如说通过信号量改变打断死循环,多线程疯狂i++操作等。看concurrent包中的源码时,volatile是必须要理解的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.07.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础概念
  • volatile原理
  • 常见问题
  • 使用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档