volatile特点:
保证可见性,可见性是指当一个线程修改了共享变量的值,其他线程可以立即得知
保证有序性?
不保证原子性(需要使用悲观锁or乐观锁)
线程栈:
每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存
变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,
在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。
volatile怎么保证多个线程之间的可见性:
每个线程在将数据操作完保存回主存之前,会加lock指令来锁定内存区域的缓存(缓存行锁定),总线通过侦听器发现数据被修改,会立即让其他线程工作内存中不一致的副本立即失效。
等到当前线程将更改后的数据write回主存后,立即执行unlock指令。
此时,其他线程再重新读取更新后的数据,再拷贝到自己的工作内存。总线侦听机制会在总线上检测线程的数据,发现有线程做了更改时准备store回主内存时,它就会立刻将其他线程工作内存中的副本置位无效,然后从新到主存获取更新后的值。
除了使用 volatile 关键字来保证内存可见性之外,使用锁也能保证变量的内存可见性。只是相比而言使用 volatile关键字开销更小,是轻量级的锁。这就是内存可见性的原理。
Volatile关键字什么时候使用:
当一个变量需要被多个线程访问,且需要修改时,比如布尔类型或者修改为固定的几个值,但是不适合做累加操作,否则会有线程安全问题
参考: