线程安全一一可见性

in 笔记 with 0 comment

Java内存模型 vs Java运行时数据区

一个可见性的栗子

image.png

image.png

梳理流程

主线程去写isRunning,子线程去读isRunning。是否打印i是子线程读取isRunning结果决定的,根据上图会不会是由于高速缓存的问题导致的呢?

揭晓答案

这是由于while中触发了JIT编译器的执行,导致isRunning就算被修改了没用,不会再去读取isRunning的值。

JIT编译器(Just In Time Compiler)

image.png

volatile关键字

Java内存模型规定:对volatile变量v的写入,与所有其他线程后续对v的读同步。即线程每次获取volatile变量的值都是最新的。保证了原子性。

image.png

image.png

Java内存模型内容细节

Shared Variables定义

image.png

Java内存模型规范这些被多个线程访问的共享变量如何巴拉巴拉。

线程间操作的定义

image.png

线程间操作:1、对共享变量的操作。2、一个线程对object加锁,其他线程拿不到这个锁受影响。3、线程第一个和最后一个操作。4、外部操作,如:一个线程操作数据库,另外的线程也会受影响。

Java内存模型还要规范线程间操作,保证可见性。

对于同步的规则定义

image.png

image.png

线程2拿到锁以后对线程1来说是可见的,线程1不能缓存。

image.png

因为有了JAVA内存模型,所以才能看到美好的世界(初始化默认值,其实默认值是乱码的,在内存中申请杂乱无章)。

线程被创建后,会在堆内存创建一个线程对象,也会创建一个线程独占空间的工作区域。

Happens-before规则定义

image.png

as-if-serial和happends-before的区别:

  1. as-if-serial是单CPU中指令重排的遵循规则。
  2. happends-before是多个线程之间的可见性规则(JMM规则)。

final在JMM中的处理

image.png

案例:

image.png

相关参考资料