Java多线程学习

目录

  1. JMM(Java Memory Model)
  2. 指令重排
  3. as-if-serial语义
  4. happens-before原则
  5. 并发编程特性

JMM(Java Memory Model)

指令重排

程序在经过编译器编译之后形成的指令序列会被CPU和编译器进行优化,提升执行效率。

as-if-serial语义

不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。编译器,runtime 和处理器都必须遵守 as-if-serial 语义。为了遵守 as-if-serial 语义,编译器和处理器不会对存在数据依赖关系的操作做重排序,因为这种重排序会改变执行结果。

happens-before原则

JMM 可以通过happens-before关系向程序员提供跨线程的内存可见性保证,即JMM对A happens-before B保证A的执行结果对B是可见的。具体有以下原则:

  1. 程序次序规则: 无论如何重排,JMM保证一个线程内最终结果和代码顺序执行结果一致

  2. 锁定规则: 一个unlock操作要先行发生于对同一个锁的lock操作

  3. volatile规则: 对一个变量写操作要早于对这个变量之后的读操作

  4. 传递规则

  5. 线程启动规则: Thread对象的start()方法先于发生对该线程的任何动作

  6. 线程中断规则: 对线程执行interrupt()肯定要优先于捕获中断信号

  7. 线程的终结规则: 线程所有操作要优先于线程死之前

  8. 对象终结规则: 一个对象初始化完成要先于finalize()方法之前

并发编程特性

  1. 原子性

JMM保证基本数据类型的变量读取赋值操作是原子性的,引用类型的变量读取和赋值操作也是原子性的。

  1. 可见性

volatile,sychronizedJUC提供的显示锁都能保证可见性。volatile保证共享变量读写都会在主内存中进行; 其他锁机制会保证锁释放之前会将变量的修改刷新到主内存中。

  1. 有序性

volatile,sychronizedJUC提供的显示锁都能保证有序性。其中volatile方式是禁止JVM和处理器对该关键字修饰的指令重排。

volatile原理是汇编代码中使用lock修饰,这类似一个内存屏障,会导致以下结果: a) 将当前缓存行的数据写回到系统内存 b) 写回内存的操作会使在其他缓存了该内存地址的数据无效