CPU多级缓存
计算机硬件架构简单图示(多CPU):
多个CPU带来的问题及解决方法:
(1)缓存一致性问题:MESI原则
(2)CPU乱序执行优化
Java内存模型(Java Memory Model,JMM)
Java内存模型与硬件架构关联
硬件架构中没有划分线程栈和堆
Java内存模型抽象结构图
- 本地内存是Java抽象出来的,包含寄存器,缓存,写缓冲区以及其他的编译器优化
- 主内存就是硬件的内存
- Java内存模型中的工作内存是CPU寄存器和高速缓存的抽象描述
- JVM中的内存模型只局限在JVM的物理内存划分
Java内存模型——同步操作与规则
八种同步操作:
- lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态
- unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
- read(读取):作用于主内存的变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用
- load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中
- use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎
- assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量
- store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的 write的操作
- write(写入):作用于主内存的变量,它把 storet操作从工作内存中一个变量的值传送到主内存的变量中
同步规则:
- 如果要把一个变量从主内存中复制到工作内存,就需要按顺寻地执行read和load操作,如果把变量从工作内存中同步回主内存中就要按顺序地执行 store和 write操作。但Java内存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行
- 不允许read和load、 store和 write操作之一单独出现
- 不允许一个线程无原因地(没有发生过任何 assign操作)把数据从工作内存同步回主内存中
- 一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或 assign)的变量。即就是对一个变量实施use和 store操作之前,必须先执行过了 assign和load操作
- 一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的 unlock操作,变量才会被解锁。Iock和 unlock必须成对出现
- 如果对一个变量执行lock操作,将会清空工作内存中此变量的值在执行引擎使用这个变量前需要重新执行load或 assign操作初始化变量的值
- 如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去 unlock一个被其他线程锁定的变量
- 对一个变量执行 unlock操作之前,必须先把此变量同步到主内存中(执行 store和 write操作)
并发的优势与风险
注:等待的IO不一定磁盘IO也可能是网络IO
线程安全
定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。
具体体现:
- 原子性:提供了互斥访问,同一时刻只能有一个线程来对它进行操作
- 可见性:一个线程对主内存的修改可以及时的被其他线程观察到
- 有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序的存在,该观察结果一般杂乱无序
0