ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

学习笔记(37):第1章 分布式基础之并发编程-探索线程安全性背后的本质之volatile 02

2021-01-22 13:57:03  阅读:180  来源: 互联网

标签:02 屏障 37 可见 指令 线程 内存 volatile 排序


立即学习:https://edu.csdn.net/course/play/29000/405251?utm_source=blogtoedu

1、如何才能 CPU层面的优化失效来解决可见性问题和指令重排序问题呢?

那就是实时让缓存失效,从内存中读取数据=》也就是搞一下 内存屏障

内存屏障作用就是 不允许指令重排序,禁用高速缓存

加入volatile关键字,就会增加这个内存屏障

2、java内存模型(JMM) 定义了共享内存中,多线程读写的规范,解决了不同平台的差异化,提供一个统一的线程安全性的一致性模型,提供了可见性和有序性问题的解决方案

3、开发的指令到执行的指令会经过三步优化

源代码=》编译器优化重排序=》(CPU层面)指令级并行重排序=》(CPU层面)内存系统重排序=》最终执行指令排序

这些优化就会造成可见性问题,所以硬件层面就又提供了内存屏障来解决这个问题,软件层面提供了调用内存屏障的方法

4、综上 volatile是如何解决可见性问题的呢?

提供了一个防止内存指令重排序的机制和通过内存屏障机制去解决可见性问题

5、那么volatile在什么情况下使用呢?

存在多个线程访问、并发访问的可能性,那么需要加volatile来保证可见性

6、引申问题 单例模式中 双重检查锁判断 instance==null

A a;

a=new A();

new A() 在操作系统中 是三个指令 会有重排序问题 所以 需要加 volatile关键字

static volatile A a;

a=new A();

7、Happens-Before模型-软件层面的一种自身解决可见性问题的模型

A Happens Before B,并不是A一定运行在B之前,而是 A的结果值对B可见

什么情况下会存在这个模型?

(1)程序顺序规则(as-if-serial)

不能改变程序的执行结果(单线程环境下,执行结果不变)

依赖问题,如果两个指令存在依赖关系,不允许重排序

int a=0;int b=1; int c=a*b;

(2)传递性规则

A Happens Before B;

B Happens Before C;

A的结果一定对C可见

(3)volatile变量规则

volatile修饰变量的写操作,一定hanppens-before 后续对vaolatile变量的读操作,因为内存屏障机制来防止指令重排序

标签:02,屏障,37,可见,指令,线程,内存,volatile,排序
来源: https://blog.csdn.net/qq_28500837/article/details/112978549

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

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

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

ICode9版权所有