Java 单例模式分为懒汉式和饿汉式,而日常使用又以懒汉式较多。
下面是一种线程安全的懒汉式单例模式的写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Singleton { private static Singleton instance; private Singleton() { } public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } |
遗憾的是该写法的效率很低,然后有人提出了DCL(Double Check Lock)来实现单例模式,即双重判断加锁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } |
它的优点是既能在需要的时候才初始化单例,又能保证线程安全,而且单例对象初始化后再调用方法不会再进行同步锁。
但是它也有缺点,第一次加载时反应较慢,也可能由于Java内存模型的原因偶尔会失败,在高并发环境下也有一定的缺陷,虽然发生的概率很小。
下面的方法是比较推荐的单例实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Singleton { private Singleton() { } public static Singleton getInstance() { return SingletonHolder.instance; } private static class SingletonHolder { private static final Singleton instance = new Singleton(); } } |
没错,就是通过静态内部类实现的单例模式。
当第一次加载 Singleton 类时并不会初始化 instance ,只有在第一次调用 getInstance 方法时才会加载 SingletonHolder 类并初始化 instance。这种方法不仅能确保线程安全,也能够保证对象的唯一性,同时也延迟了单例的实例化,所以这是推荐的单例模式实现方式。
下面还有一种比较另类的单例实现方式,那就是使用枚举,但是由于实在是太过另类,现实开发中使用得并不多。
1 2 3 4 5 6 7 |
public enum Singleton { INSTANCE; public void doSomething() { System.out.println("Do sth."); } } |
使用的时候,只需要:
1 |
Singleton.INSTANCE.doSomething(); |
使用容器实现单例模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class SingletonManager { private static Map<String, Object> objectMap = new HashMap<String, Object>(); private SingletonManager() { } public static void putInstance(String key, Object instance) { if (!objectMap.containsKey(key)) { objectMap.put(key, instance); } } public static Object getInstance(String key) { return objectMap.get(key); } } |
这种方案比上一种方案还要另类,在程序的初始阶段,将多种单例对象放入到一个统一的管理类中,在使用的时候根据 key 来获取单例对象。这种方式使我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体的实现,降低了耦合度。
- 本文固定链接: https://blog.kuoruan.com/109.html
- 转载请注明: Index 于 扩软博客 发表
捐 赠如果您觉得这篇文章有用处,请支持作者!鼓励作者写出更好更多的文章!
您的博客拥有旺盛的生命力!!