懒汉模式

懒汉模式的问题

线程安全问题
双重检查 加锁优化
编译器(JIT),cpu可能会对指令进行重排序,导致使用到尚未初始化的实例,通过加volatile关键字修饰来防止重排序

  1. public class LHanSimple {
  2. private static volatile LHanSimple lHanSimple;
  3. public LHanSimple() {
  4. }
  5. public static LHanSimple ins(){
  6. if (lHanSimple == null){
  7. synchronized (EHanSimple.class){
  8. if (lHanSimple == null){
  9. lHanSimple = new LHanSimple();
  10. }
  11. }
  12. }
  13. return lHanSimple;
  14. }
  15. }

饿汉模式

类加载的初始化阶段完成实例的初始化,本质上借助于jvm类的加载机制保证了实例的唯一性

类记载过程
1:将类信息加载到内存中,生成对应的class数据结构
2:连接:``
a 验证
b 准备(给类的静态成员变量赋默认值)
c 解析

3: 初始化

只有在真正使用对应的类的时候才完成初始化(懒加载)

  1. public class HungrySimpleClass {
  2. private static HungrySimpleClass ins = new HungrySimpleClass();
  3. public HungrySimpleClass() {
  4. }
  5. public static HungrySimpleClass getIns() {
  6. return ins;
  7. }
  8. }

静态内部类

本质上是利用类加载机制来保证线程安全
只有实际使用的时候才会触发类的初始化,所以也是懒加载的一种形式

  1. /**
  2. * 静态内部类 懒加载 调用静态类getIns方法的第一次的时候加载
  3. */
  4. public class InnerSingleClass {
  5. public InnerSingleClass() {
  6. }
  7. private static class InnerClassHolder{
  8. private static InnerClassHolder ins = new InnerClassHolder();
  9. }
  10. public static InnerClassHolder getIns() {
  11. return InnerClassHolder.ins;
  12. }
  13. }