首先讲解一下概念:
通俗的说就是一个类就只能有一个实例。
单例模式的一些特点:
第一,只能有一个实例。
第二,必须由自己创建自己的唯一实例。
第三,这个实例是面向所有类的,任何类都可以使用。
第四,构造函数不对外开发,为私有。
第五,通过枚举或者静态方法返回单例的对象。
第六,反序列化的时候不会重新构建对象。
饿汉式单例模式
public class B {
private static final B mB = new B();
//构造方法
private B(){
}
//公有的静态函数,对外暴露获取单例对象的接口
public static B getB(){
return mB;
}
}
懒汉式单例模式
public class B {
private static B mB;
private B(){}
public static synchronized B getMB(){
if(mB == null){
mB = new B();
}
return mB;
}
}
对于懒汉式,只有在用的时候才会被实例化,但是第一次加载的时候需要进行实例化,并且每次都要进行同步,造成不必要的同步的开销
Double CheckLock(DCL)单例的实现
双重检查锁定check-lock-check-act,存在问题是:第一次加载反应慢,有时可能出现锁定失效问题。
public class B {
private static B mB = null;
private B(){}
public static B getMB(){
if(mB == null){
synchronized(B.class){
mB = new B();
}
}
return mB;
}
}
静态内部类单例模式
public class B {
private B(){}
public static B getMB(){
return Holder.mB ;
}
/**
* 静态内部类
*/
private static class Holder{
private static final B mB = new B();
}
}
以上有个共同的问题是当反序列化的时候可以重新创建对象,所以都不推荐
- 防止序列化
private Object readResolve() throws ObjectStreamException{
return mB;
}
枚举的单例
所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
public enum SinletoEnum {
INSTANCE;
public void doSomething(){
//需要做的事
}
}
传承者(Inheritors)欢迎各位纠正错误,评论,吐槽!!!