volatile

volatile是java的一个关键字,他可以修饰变量,对于java并发来讲,他有不可替代的作用。

一概念的解释

原子性:在提出这个概念的人当时认为,原子是最小的单位,不可分割,所以他的意思是,在一个原子范围内的操作要不都成功,要不都失败,不可分割。

JMM:java 内存模型,java 内存模型是,一个进程内所有线程公用主内存,线程内部有私有内存,当操作时,线程会去主内存读取公共变量,拷贝副本到私有内存,当处理完成之后就会把私有内存的值写回主内存。其实线程私有内存是一个抽象概念,内部是通过缓冲区,寄存器等完成的。

可见性:指的是当线程把本地内存的值写回主内存是,会让其他线程知道。至于怎么让其他线程知道,这就不是这个概念的事。

指令重排序:java编写的.java 文件计算机是"不认识的",计算认识的只有机器码,一般理解是汇编代码。但是,javac编译器会把我们.java 编译成jvm认识的class文件,也就是中间文件。然后jvm会把class翻译成汇编语言,但我们编写的代码对于计算机来讲,他的执行效率是不高的,所以会对他进行优化,这就会造成语句(或者说成指令更准确)顺序发生变化。这也就是指令从排序。

二volatile的作用

  • volatile能够保证变量的可见性,但不能保证原子性。volatile进行写操作时,处理机会发送一条#Lock指令,这条指令的作用是
  1. 将当前处理机的缓存行数据写回内存。
  2. 使CPU里缓存了改地址的数据无效。

所以他是有效的。但他仅仅保证了一个变量,不能保证原子性,当然他对于多线程编程来讲是很有用的。

  • volatile 能够防止指令重排序,volatile的内存语义是:当写一个volatile变量时,jmm会把线程对应的工作内存的共享变量写入主内存,当读一个volatile变量时,jmm会把线程工作内存对于的共享变量置为无效,然后线程回去主内存中读取该共享变量。

三volatile内存语义的实现

在讲volatile的内存语义实现之前,先将四条内存屏障,storestore  storeload  loadload   loadstore。

s1 storestore s2 : s1的刷新会内存先于s2及后面所有的刷新会内存

s1 storeload s2 : s1的刷新会内存先于s2及后面所有的装载

s1 loadload s2 : s1的装载先于s2及后面所有的装载

s1 loadstore s2: s1的装载先于s2及其后面所有的刷新会内存。

对于volatile写,会在前面插入一条,storestore 语句,这能够保证volatile写之前,普通写都写好,然后在volatile写之后加一条storeload,这样能够保证读取的是最新的数据。对于volatile读,首先会在volatile读后面加一条loadload内存屏障,这样保证volatile读和普通读不进重排序,然后在loadload 后面加一条loadstore,这样避免了volatile读和普通写重排序。

当然对于连续使用volatile操作,处理机也会进行优化。比如,volatile读,loadload ,volatile读,loadstore,普通写,

storestore,volatile写,sstorestore ,volatile写,storeload。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值