logo头像

Always believe youself.

并发编程-5

第 5 章 (JMM)

共享模型之内存


原子性

可见性

有序性


Monitor 主要关注的是访问共享变量时,保证临界区代码的原子性

image.png

主存:所有线程都共享的数据,静态成员变量,成员变量。

工作内存: 每个线程私有的数据,局部变量。

可见性

现象:退不出去的循环

image.png

image.pngimage.png

解决方案:

变量 加 volatile,线程不会从缓存中去取值,效率有所损失,保证了数据的可见性。

它可以用来修饰成员变量和静态成员变量,他可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取他的值,线程操作 volatile 变量都是直接操作主存的。

方法一:轻量级的,可见性

image.png

方法二:重量级的

image.png

可见性 vs 原子性

volatile 只能保证了可见性,数据是最新的值,但是保证不了原子性,不能解决指令的交错。

image.pngimage.png

打印语句加锁了。

两阶段终止-volatile

image.png

同步模式-Balking

image.png

image.png

同一代码块的变量的可见性 用 synchroized 保证。

不同代码块中变量的可见性用 vilatile 来保证。

image.png

懒惰初始化。

有序性

image.png

指令重排序优化

提高CPU 指令级别的并发度,提高并发吞吐量,单线程不会有影响,只会影响在多线程。

是JIT编译器运行时的一些优化。

volatie 可以防止(禁止)指令重排序,不把主存的数据缓存到运行内存。

image.png

支持流水线的处理器

也不是分级越多越好

image.png

image.png

volatile 原理

volatile 的底层实现原理是内存屏障,Memory barrier (Memory Fence)

  • 对 volatile 变量的写指令会加入写屏障
  • 对 volatile 变量的读指令前会加入读屏障

image.png

image.png

image.png

synchroized 是可以保证原子性,可见性,有序性。共享变量完全被 sync 保护。 如果不是完全的,还是有可能被 重排序,不能阻止。

double-checked locking 问题

首次访问会同步,而之后的使用没有 sync

image.png

image.png

image.png

企业咚咚20210831210800.jpg

double-checked locking 解决

1
private static volatile Singleton INSTANCE = null;

image.png

happens-before

Happens-before 规定了 对共享变量的写操作对其它线程的读操作可见,它是可见性与有序性的一套规则总结。

image.png

image.png

image.png

image.png

image.png

image.png

线程安全单例

image.png

企业咚咚20210901153259.jpg

企业咚咚20210901161847.jpg

image.png

企业咚咚20210901162740.jpg

企业咚咚20210901163528.jpg

小结

企业咚咚20210901172021.jpg