单例模式是什么?
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式好处
通常使用单例对象都是重量级,里面有很多对象,例如线程池、缓存系统、网络请求等等,很耗资源。使用单例不用重复创建这种对象,其它地方也可以重复使用这个对象,提高性能。
单例模式特征
- 构造方法不对外开发的,一般是private
- 通过一个静态方法或者枚举返回单例类的对象
- 注意多线程的场景
- 注意单例类对象在反序列化时不会重新创建对象
单例模式分类
1. 懒汉式单例
- // 懒汉单例,第一次调用时实例化自己
- static class Singleton1 {
- // 私有的静态变量
- private static Singleton1 mInstance = null;
- private Singleton1() {
- System.out.println("懒汉式单例");
- }
- // 此时线程不安全,可加synchronize
- public static Singleton1 getInstance() {
- if (mInstance == null) {
- mInstance = new Singleton1();
- }
- return mInstance;
- }
- }
2. 饥汉式单例
- static class Singleton2 {
- private static Singleton2 sInstance = new Singleton2();
- private Singleton2() {
- }
- public static Singleton2 getInstance() {
- return sInstance;
- }
- }
3. 双重检验,DCL
- //双重校验,DCL
- static class Singleton3 {
- // 私有的静态变量
- private volatile static Singleton3 mInstance = null;
- private Singleton3() {
- System.out.println("DCL单例");
- }
- // 线程安全
- public static Singleton3 getInstance() {
- if (mInstance == null) {
- synchronized (Singleton3.class) {
- if (mInstance == null) {
- mInstance = new Singleton3();
- }
- }
- }
- return mInstance;
- }
- }
4. 静态内部类单例
- //静态内部类单例
- static class Singleton4 {
- private Singleton4() {
- }
- private static class Holder{
- private static final Singleton4 INSTANCE = new Singleton4();
- }
- public static Singleton4 getInstance() {
- return Holder.INSTANCE;
- }
- }
5. 枚举单例
- static enum Singleton5 {
- INSTANCE;
- }
6.容器类单例
- static class SingletonManager{
- private static Map<String, Object> objectMap = new HashMap<>();
- public static void registerService(String key, Object instance) {
- if (!objectMap.containsKey(key)) {
- objectMap.put(key, instance);
- }
- }
- public static Object gerService(String key) {
- return objectMap.get(key);
- }
- }