单例模式
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的一个实例,而且枚举能够避免使用反射实例化对象