单例模式

单例模式是 Java 中最简单的设计模式之一。顾名思义,单例模式确保一个类有且仅有一个实例,并提供访问该实例的全局方法。

该实例由类自身持有,外部无法通过 new 创建第二个对象,因此构造器必须设为私有。单例模式减少了频繁创建和销毁对象的内存开销,但由于构造器私有,单例类无法被继承,但可以正常实现接口。

创建一个单例类有两种基本方式,饱汉式和饿汉式。

饱汉式,类中仅声明静态实例,首次调用生成方法时再new出对象:

public class Singleton {

    private static final Singleton singleton;

    private Singleton(){}

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

}

饿汉式,在声明实例的同时就new出对象。此时getInstance方法不需要加锁,因为jvm保证了类加载过程是线程安全的:

public class Singleton {

    private static final Singleton singleton = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return singleton;
    }

}

静态内部类方式创建单一实例,此种方法是对饿汉式的改进。如果创建instance实例需要的开销非常大,又不确定是否需要用到instance实例,那么每次运行都创建一个对象的代价就有些无法接受了。由此我们将创建对象的方法塞入一个静态内部类,既保留了单一实例和线程安全,也达成了类似饱汉式的需要时再加载对象的目标。

public class Singleton {



    private static class SingletonInner{

        private static final Singleton singleton = new Singleton();

    }



    private Singleton(){}



    public static synchronized Singleton getInstance(){

        return SingletonInner.singleton;

    }



}

以上创建单例的方法都有一个缺点,那就是会被反射破坏(反射强制调用私有构造器)。使用枚举方法创建单例可以有效的解决这一问题。

public enum EnumSingleton {
 
    SINGLETON{
 
        public void innerFunc(){}
 
    };
 
    public abstract void publicFunc(){}
 
}

更多推荐