一、介绍
volatile 是轻量级的 synchrocized,, 它再多处理器开发中保证了共享变量“可见性”。
可见性:当一个线程修改一个共享变量时,另一个线程能够读到这个修改的值。
voatile 修饰的变量 比 synchrocized 成本更低. 它不会引起线程的上下文切换和调度。
二、volatile 的定义和原理
如果一个字段呗声明成volatile,java线程内存模型确保所有线程看到这个变量值是一致的。
被 volatile 修饰的变量进行写操作时,在汇编代码中多了 Lock 前缀指令。首先当前处理器会对该内存区域进行“缓存锁定”(其他处理器就无法写入操作)然后将CPU缓存行的数据写回到内存中。当一个处理器的缓存写回到内存时,其他处理器针对该内存数据的缓存将会失效,会从内存中重新读取。
处理器使用嗅探技术保证它和内存缓存、系统缓存和其他处理器的缓存在总线上保持一致。
关键字总结: 修改、独占、共享、无效;
三、volatile 的使用优化
追加字节:将共享变量追加到64字节。
在因特尔i7 、酷睿等处理器的L1、L2 或 L3 缓存的高速缓存行是64个字节,不支持部分填充缓存行。如果队列的头节点和尾节点都不足64位字节的话。处理器会将它们读取到同一个高速缓冲行当中,在多处理器下每个处理器都会缓存同样的头节点、尾节点,当一个处理器试图修改头节点时,会将整个缓存行锁定,那么在缓存一致性机制下,会导致其他处理器不能访问自己高速缓存中的尾节点,而队列的入队和出队操作则需要不停的修改头节点和尾节点,所以在多处理器的情况下会将严重影响到队列的入队和出队效率。所以使用追加64字节的方式来填满高速缓存区的缓存行,避免头节点和尾节点加载到同一个缓存行当中,使头、尾节点在修改时不互相锁定。