单例模式

1.双重检测

public class Singleton {
    private Singleton() {}  //私有构造函数
    private volatile static Singleton instance = null;  //单例对象
    //静态工厂方法
    public static Singleton getInstance() {
          if (instance == null) {      //双重检测机制
         synchronized (Singleton.class){  //同步锁
           if (instance == null) {     //双重检测机制
             instance = new Singleton();
                }
             }
          }
          return instance;
      }
}

2.饿汉模式

public class Singleton{
    private Singleton(){}

    private static Singleton instance = new Singleton();

    public static Singleton getInstance(){
        return instance;
    }
}

3.懒汉模式

public class Singleton{
    private Singleton(){}

    private static Singleton instance = null;

    public synchronized Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

 

4.使用私有内部静态类来进行单例模式的构建

public class Singleton {
    private static class LazyLoader{
        private static final Singleton instance = new Singleton();
    }

    private Singleton(){}

    public static Singleton getInstance(){
        return LazyLoader.instance;
    }

    public static void main(String[] args) throws Exception{
        Singleton instance = Singleton.getInstance();
        Singleton instanc1 = Singleton.getInstance();
        System.out.println(instanc1==instance);
        Constructor con = Singleton.class.getDeclaredConstructor();
        con.setAccessible(true);
        Singleton instance2 = (Singleton) con.newInstance();
        Singleton instance3 = (Singleton) con.newInstance();
        System.out.println(instance2==instance3);
    }
}

 从代码中可以看出来这种单例模式很容易被反射机制破坏。

5. 使用枚举来进行单例模式的构建

public enum SingletonEnum {
    INSTANCE;

    public static void main(String[] args)throws Exception{
       //获得构造器
        Constructor con = SingletonEnum.class.getDeclaredConstructor();
        //设置为可访问
        con.setAccessible(true);
        //构造两个不同的对象
        SingletonEnum singleton1 = (SingletonEnum)con.newInstance();
        SingletonEnum singleton2 = (SingletonEnum)con.newInstance();
        //验证是否是不同对象
        System.out.println(singleton1.equals(singleton2));
        SingletonEnum instance = SingletonEnum.INSTANCE;
        SingletonEnum instance1 = SingletonEnum.INSTANCE;
        System.out.println(instance==instance1);
    }
}

 

枚举instance相当于Singleton的一个实例,而且枚举能够避免使用反射实例化对象

 

posted on 2018-03-22 10:50  张小泽的小号  阅读(96)  评论(0编辑  收藏  举报

导航