没有合适的资源?快使用搜索试试~ 我知道了~
18Java内存模型:Java中的volatile有什么用?1
需积分: 0 0 下载量 171 浏览量
2022-08-03
20:27:01
上传
评论
收藏 6.3MB PDF 举报
温馨提示
试读
17页
这一点我们在第 15 节课和第 16 节课 已经分析过了。为了解决这个问题,Java 语言在规范中做出了明确的规定,也就是在 JSR 133 文档中规定了 Ja
资源详情
资源评论
资源推荐
2021/12/10 18 | Java内存模型:Java中的volatile有什么用?
https://time.geekbang.org/column/article/464954?utm_source=u_nav_web&utm_medium=u_nav_web&utm_term=u_nav_web 1/17
18 | Java内存模型:Java中的volatile有什么用?
2021-12-08 海纳
《编程高手必学的内存知识》
课程介绍
讲述:海纳
时长 19:27 大小 17.82M
你好,我是海纳。
随着这节课的开始,我们将进入到专栏的最后一个模块:自动内存管理篇。在这个模块,
你将会了解到,以 Java 为代表的托管型语言是如何自动进行内存管理和回收整理的,这将
提高你使用 Java、Python、 Go 等托管型语言的能力。
为什么我要把自动内存管理篇放到最后才讲呢?因为要理解这一篇的内容,需要软件篇和
硬件篇的知识做铺垫。比如说,在面试时,有一个问题面试官问到的频率非常高,但几乎
没有人能回答正确,因为它需要的前置知识太多。这个问题是:Java 中的 volatile 有什么
用?如何正确地使用它?
下载APP
2021/12/10 18 | Java内存模型:Java中的volatile有什么用?
https://time.geekbang.org/column/article/464954?utm_source=u_nav_web&utm_medium=u_nav_web&utm_term=u_nav_web 2/17
这个问题之所以会频繁出现在面试中,是因为 Java 并发库中大量使用了 volatile 变量,在
JVM 的研发历史上,它在各种不同的体系结构下产生了很多典型的问题。那么,在开发并
发程序的时候,深刻地理解它的作用是非常有必要的。
幸运的是,前面硬件篇的知识已经帮我们打好了足够的基础,今天我们就可以深入讨论这
个问题了。由于在这个问题中,volatile 的语义是由 Java 内存模型定义的,我们就先从
Java 内存模型这个话题聊起。
Java 内存模型
我们知道在不同的架构上,缓存一致性问题是不同的,例如 x86 采用了 TSO 模型,它的
写后写(StoreStore)和读后读(LoadLoad)完全不需要软件程序员操心,但是 Arm
的弱内存模型就要求我们自己在合适的位置添加 StoreStore barrier 和 LoadLoad
barrier。例如下面这个例子:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MemModel {
static int x = 0;
static int y = 0;
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
x = 1;
y = 1;
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (y == 0);
if (x != 1) {
System.out.println("Error!");
}
}
});
t2.start();
t1.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
2021/12/10 18 | Java内存模型:Java中的volatile有什么用?
https://time.geekbang.org/column/article/464954?utm_source=u_nav_web&utm_medium=u_nav_web&utm_term=u_nav_web 3/17
上面这个例子在 x86 机器上运行是没有问题的,但是在 Arm 机器就有概率打印出 Error。
原因是第一个线程 t1 对变量 x 和 y 的写操作的顺序是不能保证顺序的,同时,第二个线程
t2 读取 x 和 y 的时候也不保证顺序。这一点我们在 第 15 节课和 第 16 节课 已经分析
过了。
为了解决这个问题,Java 语言在规范中做出了明确的规定,也就是在 JSR 133 文档中规定
了 Java 内存模型。内存模型是用来描述编程语言在支持多线程编程中,对共享内存访问的
顺序。所以显然,在上面例子中,线程间变量共享的情况,就可以借此来解决。
在 JSR133 文档中,这个内存模型有一个专门的名字,叫 Happens-before,它规定了一
些同步动作的先后顺序。当然,这个规范也不是一蹴而就的,它也是经过了几次讨论和更
新之后才最终定稿。所以,在早期的 JVM 实现中仍然存在一些弱内存相关的问题。这些问
题我们很难称其为 bug,因为标准里的规定就有问题,虚拟机实现只是遵从了标准而已。
接下来,我们探寻一下 Happens-before 模型究竟会带来什么样的问题,这样你就能深刻
体会到 volatile 存在的意义了。
Happens-before 模型
Java 内存模型(Java Memory Model, JMM)是通过各种操作来定义的,包括对变量的
读写操作、加锁和释放锁,以及线程的启动和等待操作。JMM 为程序中的动作定义了一种
先后关系,这些关系被称为 Happens-Before 关系。要想保证操作 B 可以看到操作 A 的
结果,A 和 B 就必须满足 Happens-Before 关系,这个结论与 A 和 B 是否在同一线程中
执行无关。
我们先来看 Happens-Before 的规则,然后再对它的特点进行分析。我们要明确
Happens-Before 模型所讨论的都是同步动作,包括加锁、解锁、读写 volatile 变量、线
程启动和线程完成等。下面这几条规则中所说的操作都是指同步动作。见下面的表格:
29
30
}
}
剩余16页未读,继续阅读
SLHJ-Translator
- 粉丝: 27
- 资源: 297
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于Matlab人脸肤色定理的教师人数统计+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab霍夫曼变换的表盘读数识别+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab火灾烟雾检测源码带GUI界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的恶劣天气交通标志识别系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的霍夫曼变换的表盘示数识别+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的车道线识别系统 +源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的教室人数统计系统带Gui界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的教室人数统计系统带Gui界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB 的霍夫曼变换答题卡识别源码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab+bp神经网络的神经网络汉字识别系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0