共享模型之内存
JMM
JMM有以下几方面
1、原子性:指令不会受上下文切换的影响
2、可见性:不受cpu缓存的影响
3、有序性:保证指令不会受cpu指令并行优化的影响
可见性
volatile修饰成员变量和静态变量。避免线程从缓存中获取值。
synchronized既可以保证原子性也可以保证线程的可见性:对同一锁锁定的变量是可见的
问题:system.out.println()为什么可以导致可见性
balking模式
应用场景:
保证监控程序只运行一次
有序性
只要共享变量完全在synchronized中那么他就是有序,可见,原子的。在DCL中如果不使用volatile,在第一层检测中发现instance不为空于是就得到了返回的对象,但是由于指令的重排序导致构造方法还未完成返回的实例是一个初始化未完成的对象
volatile
通过读写屏障避免对缓存的优化
写屏障:保证该屏障之前对共享变量的改动都写到主存中
读屏障:保证该屏障之后对共享变量的读取加载的是主存中最新的数据
使用场景:一个线程写,其他线程读的情况。DCL中保证同步代码块外的共享变量的有序
单例模式的实现
1、枚举类也是类,继承了enum类
2、静态内部类,类加载是懒惰的,只有在使用这个类时才会加载,内部类中的静态实例也只会初始化一次。