Java内存模型是定义线程共享的变量的访问规则(实例字段、静态字段和构成数组对象的元素),但不包括线程私有的局部变量和方法参数。
1.主内存与工作内存
Java内存模型规定,所有的变量都必须存储在主内存中。
线程使用到的变量保存在线程工作内存中,其实主内存的副本拷贝。
2. 内存间的交互操作
- lock : 作用于主内存中的变量,将变量标识为线程独占的。
- unlock :作用于主内存中的变量,将线程独占的变量解锁。
- read :作用于主内存中的变量,将一个变量值从主内存传输到工作内存。
- load :作用于工作内存的变量,将read读入的值放入工作内存的变量副本中。
- use :作用于工作内存的变量,使用该变量。
- assign :作用于工作内存的变量,为变量赋值。
- store :作用于工作内存的变量,把工作内存的值传递给主内存。
- write :作用于主内存的变量,把store的值放入主内存变量中。
3. 对于volatile型变量的特殊规则
3.1 volatile关键字的作用
- 保证此变量对所有线程的可见性。(当一条线程修改了变量值,其他线程是立即得知的,但不代表是线程安全的)
- 禁止指令重排序优化。
3.2 对于long和double型变量的特殊规则(不重要)
long和double的非原子协定。
4. 原子性、可见性和有序性
4.1原子性
Java内存模型直接保证基本数据类型的访问时具有原子性的。使用synchronized代码块保证更大范围内的原子性。
4.2 可见性
volatile可以保证可见性。此外,synchronized和final也可以保证可见性。
4.3 有序性
使用synchronized以及volatile保证有序性。
5. Java与线程
5.1 线程的实现
- 使用内核线程实现
- 使用用户线程实现
- 使用用户线程加轻量级进程混合实现
5.2 Java线程调度
- 协同式调度
- 抢占式调度
5.3 Java线程的状态
- 新建——创建后尚未启动的线程
- 运行——有可能正在执行,也有可能正在等待CPU为它分配时间
- 无限期等待——不会被分配时间,必须等待其他线程将其唤醒。
- 限期等待——一定时间后,被系统自动唤醒。
- 阻塞——等待进入同步区域,或者说等待一个排它锁。
- 结束——已经终止的线程。