volatile的概念:
volatile与synchronized关键字是多线程并发编程中非常重要的知识点,通常被用于修饰变量。相比于synchroinized来说,volatile要轻量很多,执行的成本会更低。原因是volatile不会引起线程上下文的切换和调度,但是它与synchronized的意义其实是有区别的。synchronized关键字主要体现的是互斥性,而volatile体现的便是可见性、原子性。从根本上来说,volatile用于多线程之间内存的共享。
volatile使用意义:
Java内存模型:
从下面图中可以看出,java的内存模型定义了主内存和本地内存,这是一种抽象的概念。主内存是所有线程可以共享的区域,本地内存为线程私有化。为了提高性能,线程通常不直接从主内存中读出和写入内容,而是通过本地内存,并通过一定的刷新机制进行内容同步。本文主要介绍volatile相关知识,关于java内存模型内容在后面专题分析。以下分别为不使用volatile和使用volatile关键字的区别:
不使用volatile关键字 使用volatile关键字volatile意义:
上图看出,当线程A与线程B访问同一个变量a时,若在线程A中将a的值从0修改为1,线程B中读取变量a的值,依然是0。而使用volatile关键字之后情况就不一样,线程B读取到a的值为1。原因在与,没有使用volatile关键字修饰变量时,线程A的修改只是在本地内存A中,不会同步到主内存,线程B也只是从本地内存B中读取,因此无法实现修改同步。使用volatile关键字之后,在线程A中修改了a的值,会将修改从本地内存A写入到主内存中,而当线程B读取a的值时,会直接从主内存中读取,并刷新本地内存B。因此,线程A与线程B便能够实现内存之间的共享了,实现内存的可见性。
volatile实现原理:
被修饰变量值修改时处理器会将缓存行数据写入到主内存中
如果变量被声明为volatile,当进行写操作时,JVM会向处理器发送一条Lock前缀的指令,然后将变量在缓存中所修改的值写入到系统内存中。
缓存一致性协议
如果volatile仅仅只有将缓存数据写入到系统主存的能力,并不能实现线程之间的共享。当有多个处理器存在的情况下,为了保证各个处理器缓存内容的一致性,处理器会实现缓存一致性协议。每个处理器通过嗅探在总线上传播的数据,检查自己缓存的值是不是过期,当处理器发现自己缓存中所对应变量的内存地址被修改时,就会将当前缓存行标志成无效状态,当处理器需要读取或是修改数据时,会直接从主内存中加载数据到缓存中,保证数据的一致性。
结束语
本篇只是概括性介绍volatile的一些基础知识,对于原理的分析比较简单易懂。如果要深入了解可以读以下《java并发编程的艺术》一书,书中有比较详细的知识,或是参考这篇文章 正确使用 Volatile 变量
网友评论