ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

04 - volatile 原理分析

2022-08-17 17:02:04  阅读:163  来源: 互联网

标签:volatile 变量 04 副本 线程 内存 原理 数据 cpu


什么是 Volatile

能够保证线程可见性,当一个线程修改主内存中共享变量时,能够保证对另外一个线程可见性,

但是注意他不能够保证共享变量的原子性问题。

Volatile的特性

可见性

能够保证线程可见性,当一个线程修改主内存中共享变量时,能够保证对另外一个线程可见性,

但是注意他不能够保证共享变量的原子性问题。

顺序性

程序执行程序按照代码的先后顺序执行。

原子性

即一个操作或者多个操作 要么全部执行并且执行的过程,要么失败。

Volatile可见性

public class Mayikt extends Thread {
    /**
     * lock 锁 汇编的指令 强制修改值,立马刷新主内存中 另外线程立马可见刷新主内存数据
     */
    private static volatile boolean FLAG = true;

    @Override
    public void run() {
        // 这个 FLAG 是 CPU 里面高速缓存里的数据,不是主内存中共享变量的数据
        while (FLAG) {
            System.out.println("子线程");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new Mayikt().start();
        Thread.sleep(1000);
        FLAG = false;
        System.out.println("主线程退出");
    }
}

为什么会产生可见性的原因

CPU每次从主内存读取数据比较慢,而现代的CPU通常涉及多级缓存,CPU读主内存。

按照空间局部性原则加载 局部快到缓存中。

因为我们CPU读取主内存共享变量的数据时候,效率是非常低,所以对每个CPU设置 对应的高速缓存 L1、L2、L3 缓存我们共享变量主内存中的副本。

相当于每个CPU对应共享变量的副本,副本与副本之间可能会存在一个数据不一致性的问题。

比如线程线程B修改的某个副本值,线程A的副本可能不可见。导致可见性问题。

JMM内存模型

Java内存模型定义的是一种抽象的概念,定义屏蔽java程序对不同的操作系统的内存访问差异。

主内存:存放我们共享变量的数据

工作内存:每个CPU对共享变量(主内存)的副本。堆+方法区

JMM八大同步规范

  1. lock(锁定):作用于 主内存的变量,把一个变量标记为一条线程独占状态

  2. unlock(解锁):作用于 主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定

  3. read(读取):作用于 主内存的变量,把一个变量值从主内存传输到线程的 工作内存中,以便随后的load动作使用

  4. load(载入):作用于 工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中

  5. use(使用):作用于 工作内存的变量,把工作内存中的一个变量值传递给执行引擎

  6. assign(赋值):作用于 工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量

  7. store(存储):作用于 工作内存的变量,把工作内存中的一个变量的值传送到 主内存中,以便随后的write的操作

  8. write(写入):作用于 工作内存的变量,它把store操作从工作内存中的一个变量的值传送到 主内存的变量中

Volatile汇编lock指令

  1. 将当前处理器缓存行数据立刻写入主内存中。

  2. 写的操作会触发总线嗅探机制,同步更新主内存的值。

Volatile的底层实现原理

通过汇编lock前缀指令触发底层锁(总线)的机制

主要帮助我们解决多个不同cpu之间三级缓存之间数据同步

总线

总线:工作内存访问到主内存数据的时候,都会经过我们的总线。

总线主要能够帮助我们解决:多个不同CPU核之间的工作内存副本数据一致性问题。

总线分为总线索和MESI协议

总线锁

当一个cpu(线程)访问到我们主内存中的数据时候,往总线总发出一个Lock锁的信号,其他的线程不能够对该主内存做任何操作,变为阻塞状态。该模式,存在非常大的缺陷,就是将并行的程序,变为串行,没有真正发挥出cpu多核的好处。

MESI协议

  1. M 修改 (Modified) 这行数据有效,数据被修改了,和主内存中的数据不一致,数据只存在于本Cache中。

  2. E 独享、互斥 (Exclusive) 这行数据有效,数据和主内存中的数据一致,数据只存在于本Cache中。

  3. S 共享 (Shared) 这行数据有效,数据和主内存中的数据一致,数据存在于很多Cache中。

  4. I 无效 (Invalid) 这行数据无效。

E:独享:当只有一个cpu线程的情况下,cpu副本数据与主内存数据如果保持一致的情况下,则该cpu状态为E状态 独享。

S:共享:在多个cpu线程的情况了下,每个cpu副本之间数据如果保持一致的情况下,则当前cpu状态为S

M:如果当前cpu副本数据如果与主内存中的数据不一致的情况下,则当前cpu状态为M

I: 总线嗅探机制发现 状态为m的情况下,则会将该cpu改为i状态 无效

该cpu缓存主动获取主内存的数据同步更新。

如果状态是M的情况下,则使用嗅探机制通知其他的CPU工作内存副本状态为I无效状态,则 刷新主内存数据到本地中,从而多核cpu数据的一致性。

标签:volatile,变量,04,副本,线程,内存,原理,数据,cpu
来源: https://www.cnblogs.com/YeQuShangHun/p/16595853.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有