写点什么

我看 JAVA 之 并发编程【四】线程安全与 JMM

用户头像
awen
关注
发布于: 2021 年 08 月 12 日
我看 JAVA 之 并发编程【四】线程安全与JMM

我看 JAVA 之 并发编程【四】线程安全与 JMM

线程安全

概念


三大特性

原子性

即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

    JDK64 位中对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行。

y =10 是原子的。

y=x 就不是原子的:有两个步骤 1,读取 x 值;2,赋值给 y

i++也不是原子的,大家可以思考下为什么。


通过如下三种方式可以保障原子性:

  1. Synchronized

  2. Lock

  3. Atomic 原子工具类

可见性

指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

通过如下三种方式可以保障可见性:

  1. ‍Synchronized

  2. ‍volatile

  3. Lock

有序性

即程序执行的顺序按照代码的先后顺序执行。当然可能会遇到编译器重排,指令重排等,但不影响计算结果。


通过如下三种方式可以保障有序性:

  1. ‍Synchronized

  2. ‍volatile

  3. Lock

JMM

体系结构

JMM 定义了 8 个同步操作,如下:

同步流程

happens-before 原则

Java 内存模型具备一些先天的“有序性”,即不需要通过任何手段就能够得到保证的有序性,这个通常也称为 happens-before 原则。如果两个操作的执行次序无法从 happens-before 原则推导出来,那么它们就不能保证它们的有序性,虚拟机可以随意地对它们进行重排序。

下面就来具体介绍下 happens-before 原则(先行发生原则):

(1)程序顺序规则:一个线程中的每个操作,happens-before 于该线程中的任意后续操作。

(2)监视器锁规则:对一个锁的解锁,happens-before 于随后对这个锁的加锁。

(3)volatile 变量规则:对一个 volatile 域的写,happens-before 于任意后续对这个 volatile 域的读。

(4)传递性:如果 A happens-before B,且 B happens-before C,那么 A happens-before C。

(5)start()规则:Thread 对象的 start()方法先行发生于此线程的每个一个动作。

(6)Join()规则:如果线程 A 执行操作 ThreadB.join()并成功返回,那么线程 B 中的任意操作 happens-before 于线程 A 从 ThreadB.join()操作成功返回。

(7)程序中断规则:对线程 interrupted()方法的调用先行于被中断线程的代码检测到中断时间的发生。

(8)对象 finalize 规则:一个对象的初始化完成(构造函数执行结束)先行于发生它的 finalize()方法的开始。

volatile

volatile 关键字保证了变量的内存可见性以及有序性。简单来说就是通过缓存一致性协议(MESI)和内存屏障来实现。


用户头像

awen

关注

Things happen for a reason. 2019.11.15 加入

还未添加个人简介

评论

发布
暂无评论
我看 JAVA 之 并发编程【四】线程安全与JMM