多线程 - (三)volatile

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仅仅只有将缓存数据写入到系统主存的能力,并不能实现线程之间的共享。当有多个处理器存在的情况下,为了保证各个处理器缓存内容的一致性,处理器会实现 缓存一致性协议 。每个处理器通过嗅探在总线上传播的数据,检查自己缓存的值是不是过期,当处理器发现自己缓存中所对应变量的内存地址被修改时,就会将当前缓存行标志成无效状态,当处理器需要读取或是修改数据时,会直接从主内存中加载数据到缓存中,保证数据的一致性。

猜你喜欢

转载自blog.csdn.net/qq_28988969/article/details/80592730