单例模式

101 阅读1分钟

使用场景

需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)
频繁获取的配置文件啥的

创建过程

1、创建实例
2、构造器私有化(外部不能使用构造器创建对象)
3、返回实例的方法

饿汉式

线程安全,调用效率高,但是不能延时加载

public  class Tong{
    private  static Tong instance = new Tong;
    private Tong(){}
    public static  Tong getInstance(){
        return instance;
    }
}

懒汉式

线程安全,调用效率不高,但是能延时加载

public class Tong {
    private static Tong tong;
    private Tong() {

    }
    public static synchronized Tong Tong() {
        if (tong == null) {
            tong=new Tong();
        }
        return tong;
    }
}

双重检查式

DCL也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用)

public class Tong {
  private static Tong tong;
  private Tong(){}
  public static Tong getInstance(){
      if(tong==null){
          synchronized (Tong.class){
              if(tong==null){
                  tong= new Tong();
              }
          }
      }
      return tong;
  }
}

上面的也不好,发生cpu指令重排序的话,还是会有点问题,但是发生概率不怎么高
volatile版本


class Foo {  
    private volatile Helper helper = null;
    private Foo(){}  
    public Helper getHelper() {  
        if (helper == null) {  
            synchronized (this) {  
                if (helper == null)  
                 //(jvm new对象的过程 申请内存->变量初始化->赋值给helper)
                    helper = new Helper();//指令重排序 上面的顺序乱了,可能会导致对象值不准,volatile可以防止指令重排序
            }  
        }  
        return helper;  
    }  
}  

静态内部类实现模式

线程安全,调用效率高,可以延时加载

public class Tong {
    
    private  static class TongInstance{
        private final static Tong tongInstance=new Tong();
    }
    private Tong(){}
    public static Tong getInstance(){
        return TongInstance.tongInstance;
    }
}