一、volatlite简介
volatile的文章还是很多的,现在也是面试中问的比较多的一个点,最近看了深入理解Java内存模型这本书,比较短,pdf版的,只有八十页左右,想到volatile的特性跟JMM相关联的地方,现在记录一下自己的所学,如有错误欢迎大神纠正。首先volatile使用方法是用来修饰公共变量,保证变量在多线程环境中保证可见性和有序性,在有些特别的条件下可以保证原子性。可以总结为他有两个作用:(1)保证可见性:防止编译器为了提高速度将一个变量缓存到寄存器内而不写回内存。(2)保证指令不重新排:防止编译器调整操作volatile变量的指令顺序。
二、volatile和JMM
1、JMM简介
首先我们先介绍一下JMM(Java内存模型),它是一个抽象的概念,是围绕原子性、有序性、可见性展开的。简单举个例子:有线程A和B,他们之间想要通信,要经过两块地方,一个是主内存,这里有很多共享变量,第二是线程A和B的本地内存,这里存放的是共享变量副本。那么A和B通信要经过两步:1、A将本地内存A中的共享变量刷新到主内存中去。2、B去主内存中读取。这就是一个简单的JMM控制两条线程通信的模型。等拜读完内存模型全篇后出一篇详解JMM的博客。
2、重排序
重排序是JMM中的一个重要概念,它分为三种:第一个是编译器优化的重排序,第二个是指令集并行的重排序,第三个是内存系统的重排序。Java源代码到最终执行的指令序列会经历这三种重排序。
3、MESI缓存一致性协议
这是cpu的一个协议,现在cpu大部分都是多核的,多核同时还有多缓存,这是为了提高cpu的访问速度,当两个核或多个核同时访问同一个变量时,缓存如何进行同步呢,这时候需要MESI协议了,可以简单理解为cpu核心、一级缓存、二级缓存、三级缓存。此处深入点等后期出一片MESI详解。
三、总结
volatile的作用是禁止重排序和可见性,比方我们写了一个银行系统,对账户分别有写和读方法,那么这时候没有数据依赖性可能会发生重排序,结果可能会发生改变,而volatile的禁止重排序用在此处就恰到好处,禁止掉重排序。不过具体情况具体分析。