Volatile的实现原理

Posted by Kei Wu on April 28, 2016

Volatile的官方定义

Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供 了volatile,在某些情况下比锁更加方便。如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。

Volatile的实现原理

处理器为了提高处理速度,不直接和内存进行通讯,而是将系统内存的数据独到内部缓存后再进行操作,但操作完后不知什么时候会写到内存。 如果对声明了volatile变量进行写操作时,JVM会向处理器发送一条Lock前缀的指令,将这个变量所在缓存行的数据写会到系统内存。 但这时候其他处理器的缓存还是旧的,所以在多处理器环境下,为了保证各个处理器缓存一致,每个处理会通过嗅探在总线上传播的数据来检查 自己的缓存是否过期,当处理器发现自己缓存行对应的内存地址被修改了,就会将当前处理器的缓存行设置成无效状态,当处理器要对这个数据 进行修改操作时,会强制重新从系统内存把数据读到处理器缓存里。

Volatile的使用优化

JDK7并发包里面的队列集合类LinkedTransferQueue,在使用volatile变量时,使用一种追加字节的方式来优化队列出队和入队的性能。
在高速缓存行是64个字节宽的处理器上面(不支持部分填充缓存行),如果队列的头节点和尾节点都不足64字节的时候,处理器会将他们都读到 同一个高速缓存行中,在多处理器环境下,一个处理器师徒修改自己的高速缓存的头节点时,会将整个缓存行锁定,导致其他处理器不能访问自 己高速缓存中的尾节点,而队列的操作需要不停的修改头结点和尾节点,所以这就严重影像了队列的出队入队效率。

参考:http://www.infoq.com/cn/articles/ftf-java-volatile