应用最广的设计模式——单例模式

时间:2019-09-21
本文章向大家介绍应用最广的设计模式——单例模式,主要包括应用最广的设计模式——单例模式使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
  • 介绍

单例模式是应用最广的模式之一,也可能是很多初级工程师唯一会使用的设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需拥有一个全局对象,这样有利于我们协调系统整体的行为。

  • 定义

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例

  • 使用场景

确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个。例如,创建一个对象需要消耗的资源过多,需要访问IO和数据库等资源。

  • 代码实现

饿汉单例模式:生命静态对象时就已经初始化instance,但是可能不需要它初始化,我们更希望在使用到单例的时候再初始化。

public class Singleton {

private static final Singleton instance = new Singleton();

private Singleton() {
}

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

  懒汉单例模式:在第一次调用getInstance时才初始化instance。但是第一次初始化之后,每次调用都会进行同步,这样会消耗不必要的资源。

public class Singleton {

private static Singleton instance;

private Singleton() {
}

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

  Double Check Lock(DCL):优点是既能够在需要时才初始化单例,又能够确保线程安全,且单例对象初始化后调用getInstance不进行同步锁。但是由于指令重排序问题,所以DCL会失效(解决方式可以为instance加上volatile关键字,从而禁止指令重排序)。

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

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

  静态内部类单例模式:最推荐使用的单例模式。第一次加载Singleton类时并不会初始化instance,只有在第一次调用Singleton的getInstance方法时才会导致instance被初始化。因此,第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能够保证线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化。

public class Singleton {

    private Singleton() {
    }

    public static Singleton getInstance() {

        return SingletonHolder.instance;
    }

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

  使用容器实现单例模式:在程序的初始,将多种单例类型注入到一个统一的管理类中,在使用时根据key获取对象对应类型的对象。这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体实现,降低了耦合度。

import java.util.HashMap;
import java.util.Map;

public class SingletonManager {
    private static Map<String, Object> objMap = new HashMap<>();

    private SingletonManager() {
    }

    public static void registerService(String key, Object instance) {
        if (!objMap.containsKey(key))
            objMap.put(key, instance);
    }

    public static Object getService(String key) {
        return objMap.get(key);
    }
}

  

原文地址:https://www.cnblogs.com/zty-lyq/p/11561394.html