1 内存模型
保证从Java语言到JVM执行class文件的标准
1.1 jvm内存结构
java虚拟机运行时数据区
- 线程公共 : 方法区和堆
- 线程私有 : 虚拟机栈、本地方法栈、程序计数器
1.2 java 对象模型
对象本身的存储模型
包含 mark word 、对象头、实例数据
1.2 java内存模型 (Java Memory Model JMM)
1.2.1 为什么需要JMM
是一组规范,保证并发安全,使多线程运行可预期;保证在不同操作系统虚拟机上执行结果一致。
最重要的三点内容:重排序、可见性、原子性
1.2.2 重排序
线程代码执行顺序没有严格按照java代码中顺序执行;用于提高运行速度
- 编译优化
- CPU指令重排
1.2.3 可见性
JMM抽象:主内存与本地内存
- 所有共享变量存储在主内存
- 线程读写本地内存。然后同步到主内存
- Happens Before
- 动作A发生在B之前,保证B能看到A,保证可见性
- 锁操作会保证可见性、volatile、join; voaltile能实现轻量级同步(近朱者赤)
- 传递性
hb(A,B) hb(B,C) = hb(A,C)
1.2.4 volatile
可见性和禁止重排序
一种同步机制、不会发生上下文切换
不适用 : a++
使用场合:
- boolean flag, 因为纯赋值是原子操作、volatile保证可见性
- 触发器,即保证同一线程上所有赋值语句的正确性
1.2.5 原子性
java中的原子操作
- 除long和double之外的基本类型赋值
- 所有引用的赋值操作
- 一些工具类的操作 (Atomic)
在32位的虚拟机上long和double是非原子的,需要用volatile标注保证原子性;但在实际商用虚拟机汇总,不会出现,因为已经保证了。
2 单例模型
- 饿汉式
- 懒汉式:双重检查、volatile(新建对象不是原子操作)
- 静态内部类
- 枚举 :简单、保证线程安全、防止反序列化破坏安全性。最为推荐