JMM
Java内存模型(即Java Memory Model,简称JMM)本身是一种抽象概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量的访问方式。由于JVM运行程序的实体是线程,每个线程创建时,JVM 会给其创建一个工作内存,用于存储线程私有数据,线程公有数据存储在主内存中。当线程需要操作共有数据时,会将数据从主内存拷贝到其私有的工作内存中,操作工作内存中的副本,然后再将副本写回主内存。如图:
JMM与前面提到的JVM的内存区域在某种程度来说,有其相似点,都存在共享数据区域和私有数据区域。
JMM与硬件内存架构
硬件内存架构
Java线程与硬件处理器
在Windows与Linux系统上,Java线程的实现时基于一对一的线程模型,所谓的一对一模型,指通过语言级别层面程序去间接调用系统内核的线程模型,即在使用Java线程时,Java虚拟机内部是转而调用当前操作系统的内核线程来完成当前任务。
术语:内核线程(Kernel-Level Thread, KLT),它是由操作系统内核支持的线程,这种线程是由操作系统内核来完成线程切换,内核通过操作调度器进而对线程进行调度,并将线程的任务映射到各个处理器上。每个内核线程可以视为内核的一个分身,Kernel <-> thread。
在Java开发中,使用new Thread().start(); 创建一个Java线程,通过Java线程映射一个内核线程,进而由操作系统内核将任务映射到各个处理器。这种一对一的关系即上面提到的一对一线程模型。如图:
Java并发特性
- 原子性
操作不可中断,例:
private static int i = 0;
public void print() {
i = i + 1;
System.out.println("i: "+i);
}
线程1,线程2同时访问print方法,打印【1,2】 / 【2,1】(指令重排)
指令重排
编译器优化的重排
指令并行的重排
内存系统的重排
- 有序性
多线程下,本线程内,所有操作视为有序行为,视其他线程操作为无序行为。(指令重排+工作内存、主内存同步延迟)
- 可见性
多线程下,线程A修改共享变量X的值,未写回主内存时,线程B无法获取修改后的X,即A线程工作内存中的X对B线程不可见