Java趣味编程-单例模式的最佳推荐实现方式

单例模式仅有一个实例,自行实例化并提供一个访问它的全局公有静态方法。

注意:单例模式需要注意场景的使用,项目中过多使用单例无益处。

单例的使用情况

一般有两种情况下会应用到单例模式:

  • 一:
    产生的对象会消耗过多的资源,为避免频繁地创建与销毁对象对资源的浪费。
    • 数据库操作
    • 网络请求
    • 线程池(threadpool)
    • IO访问操作
    • 任务调度器
  • 二:
    应用系统中只能有一个实例存在,过多的实例会导致应用系统的不稳定。
    • 操作系统注册表
    • android InputMethodManager
    • android BluetoothOppManager

单例优缺点

  • 优:
    可以减少系统内存开支,减少系统性能开销,避免对资源的多重占用、同时操作。
  • 缺:
    扩展很困难,容易引发内存泄露,测试困难,一定程度上违背了单一职责原则,进程被杀时可能有状态不一致问题。应用退出需要注意单例释放。

推荐一 双重检查锁定Double Check Lock(DCL)方式:

此方法的“Double-Check”体现在进行了两次if (singleton == null)的检查,这样既同步代码块保证了线程安全,同时实例化的代码也只会执行一次,实例化后同步操作不会再被执行,从而高并发下效率提升很多。

注意: JDK 普遍都已超过 1.4,只要在定义单例时加上 1.5 及以上版本具体化了的 volatile关键字,即可保证执行的顺序,从而使单例起效。

//1.4及以下版本定义
private static volatile Singleton mInstance;
//1.5以上版本定义
public final class Singleton {
    private static Singleton mInstance;

    private Singleton() {
    }

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

推荐二 《Java并发编程实践》极为推崇静态内部类方式:

利用了 classloder 的机制来保证初始化 instance 时只会有一个。这种方式的 Singleton 类被装载时,只要 SingletonHolder 类还没有被主动使用,instance 就不会被初始化。只有在显式调用getInstance()方法时,才会装载 SingletonHolder 类,从而实例化对象。

public final class Singleton {
    private Singleton() {
    }

    public static  final Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }

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

你可能感兴趣的:(Java趣味编程-单例模式的最佳推荐实现方式)