单例模式是保证系统实例唯一性的重要手段。单例模式首先通过将类的实例化方法私有化来防止程序通过其他方式创建该类的实例,然后通过提供一个全局唯一获取该类实例的方法帮助用户获取类的实例。
单例模式的设计保证了一个类在整个系统中同一时刻只有一个实例存在,主要被用于一个全局类的对象在多个地方使用并且对象的状态是全局变化的场景下。
需要注意的是,单例模式的类构造函数是私有的,只能由自身创建和销毁对象。
1. 懒汉模式
public class LazySingleton{ private static LazySingleton instance; private LazySingleton(){} public static synchronized LazySingleton getInstance(){ if(instance == null){ instance = new LazySingleton(); } return instance; } }
之所以instance定位为静态的,是因为静态属性或方法是属于类的,能够很好的保障单例对象的唯一性。
2. 饿汉模式
public class HungrySingleton{ private static HungrySingleton instance = new LazySingleton(); private HungrySingleton(){} public static HungrySingleton getInstance(){ return instance; } }
3.静态内部类
public class Singleton{ public static class SingletonHolder{ private static final Singleton INSTANCE = new Singleton(); } private Singleton(){} public static final Singleton getInstance(){ return SingletonHolder.INSTANCE; } }
将对象的定义和初始化放在静态内部类中完成,因为静态内部类在JVM中是唯一的,这很好的保障了单例对象的唯一性。
4.双重校验锁
public class Lock2Singleton{ private volatile static Lock2Singleton instance; private Lock2Singleton(){} public static Lock2Singleton getInstance(){ if(instance == null){ synchronized(Lock2Singleton.class){ if(instance == null){ instance = new Lock2Singleton(); } } } return instance; } }
双锁模式是在懒汉模式的基础上做进一步优化,给静态对象加上volatile锁来保障初始化时对象的唯一性,在获取对象时通过synchronized来给单例类加锁来保障操作的唯一性。