来源

在 JDK1.2 之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而在当前的 Java 内存模型下,线程可以把变量保存本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。要解决这个问题,就需要把变量声明为volatile,这就指示 JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。

作用

volatile 保证内存可见性和禁止指令重排(编译器生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序)

同时,volatile 可以提供部分原子性(对任意单个volatile变量的读/写具有原子性,但类似于valatile++这种符号操作不具有原子性 。因为自增操作是不具备原子性的,它包括读取变量的原始值、进行加1操作、写入工作内存。那么就是说自增操作的三个子操作可能会分割开执行)

volatile 用于多线程环境下的单次操作(单次读或者单次写)。

实现原理

有volatile变量修饰的共享变量进行写操作时会多出第二行lock前缀指令的汇编代码。其作用如下:

1、将当前处理器缓存行的数据写回到系统内存

2、这个写回内存的操作会使得在其他CPU里缓存了该内存地址的数据无效。之后其他CPU访问该内存地址时,会强制进行缓存行填充。

实际上也相当于一个内存屏障,它保证了指令重排序时不会将内存屏障后面的指令放到前面来执行。

用途

可以通过volatile操作实现线程间通信

为了提供一种比所更轻量级的线程之间通信的机制,JSR-133决定增强volatile内存语义,严格限制volatile变量与普通变量之间的重排序,确保volatile的写-读和锁的释放-获取具有相同的内存含义。

volatile仅能保证对单个volatile变量的读/写具有原子性,而锁的互斥执行的特性可以确保对整个临界区代码的执行具有原子性。功能上,锁比volatile强大。在可伸缩性和执行性能上,volatile更有优势。

最新文章

  1. Lua笔记
  2. Eclipse启动参数
  3. iOS 保持界面流畅的技巧 (转载)
  4. python selenium 操作chrome
  5. zookeeper系列之通信模型(转)
  6. CSS样式选择器
  7. linux中find命令的使用
  8. Mysql 复习
  9. 常用的各种标准下载网站(HB GB GJB MH)
  10. FIRST集和FOLLOW集
  11. Exchange Cards(dfs)
  12. openwrt uci
  13. C# new和override的区别
  14. 【C和指针】笔记1
  15. SG函数和SG定理【详解】
  16. elasticsearch启动常见错误
  17. 阻塞IO服务器模型之单线程服务器模型
  18. 【原创精品】mac 彻底卸载趋势科技
  19. react-router路由地址变了页面却没有跳转的解决办法
  20. Tesseract-ocr 安装与使用

热门文章

  1. 用python实现矩阵转置,python3 中zip()函数
  2. CNN更新换代!性能提升算力减半,还即插即用
  3. sql server 数据库安装手册
  4. link与@import区别整理,一个表格带你了解
  5. Python数据库之数据操作
  6. NKOJ3775 数列操作
  7. centos8系统下docker安装jenkins
  8. 页面静态化--Thymeleaf
  9. Jmeter压力测试笔记(5)问题原因
  10. 11. SpringCloud实战项目-初始化数据库和表