设计模式:单例模式

单例模式:

定义:
确保某一个类只有一个实例,并且自行实例化并向整个系统提供这个实例或者提供一个访问它的全局访问点

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

实现方式流程:
1、构造函数不对外开放,一般为Private
2、通过一个静态方法或者枚举返回单例对象
3、确保单例类的对象有且只有一个,尤其是在多线程的情况下
4、确保单例对象在反序列化时不会被重新构建对象

单例模式的六种写法:
1、
饿汉模式

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {
    }

    public static Singleton getSingletonInstance() {
        return singleton;
    }
}

优点:
1、在类加载的时候初始化,类加载较慢,获取对象速度快
2、基于类加载机制,避免了多线程的同步问题
缺点:
1、在类加载的时候完成初始化,没有达到懒加载的效果
2、从来没有被使用过,就会造成内存的浪费

2、
懒汉模式(线程不安全)

public class Singleton {
    private static Singleton singleton;

    private Singleton() {
    }

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

优点:
懒汉陌生声明一个静态对象,在用户第一次调用的时候初始化,节省了资源
缺点:
第一次加载需要实例化,反应稍慢一些,并且在多线程不安全
.

3
懒汉模式(线程安全)

public class Singleton {
    private static Singleton singleton;

    private Singleton() {
    }

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

优点:适应用于多线程
缺点:每次获取实例的时候都需要进行同步,造成不必要的同步开销

4
双重检查模式(DCL)

public class Singleton {
    private volatile static Singleton singleton;

    private Singleton() {
    }

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

优点
两次判空,第一次为了不必要的同步,二次判断实例是不是null,资源利率高,效率高, 第一次获取实例时才被初始化
总体来说:一定程度上解决了资源的消耗和多余的同步、线程安全等
缺点: volatile影响性能,第一次加载慢一些,在高并发的情况下也有一定的缺陷

5
静态内部类单例

public class Singleton {

    private Singleton() {
    }
    public static Singleton getSingletonInstance() {
       return  SingletonHolder.singletonA;
    }
    private static class SingletonHolder{
        private static  final  Singleton singletonA=new Singleton();
    }
}

优点:第一次加载Singleton类时并不会初始化singletonA,只有第一次调用getSingletonInstance方法时虚拟机加载SingletonHolder并初始化singletonA,这样不仅能确保线程安全,也能保证Singleton类的唯一性。

6
枚举单例

public enum Singleton {
    SINGLETON;
    public void doSomeThing() {
    }
}

默认枚举实例创建是线程安全的,并且在任何情况下都是单例,优点就是简单,使用率不高

备注: 将一个单例实例对象写到磁盘在读回来,从而获得一个实例
防止单例模式被反序列化,加上鞋面这句话
private Object readResole()throws ObjectStreamExceptiuon{
retuen singleton;
}

总结:

优点
1、由于单例模式在内存中只有一个实例,所以,减少了内存开支,特别是一个对象需要频繁的创建、销毁时、而且常见或者销毁性能又无法优化,单例模式的优点就很明显
2、由于单例模式只生成一个实例,所以,减少了系统的性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永驻内存的方式来解决
3、单例模式可以避免对资源的多重占用
4、单例模式可以设置全局的访问点,优化和共享资源访问

缺点
1、单例模式一般没有接口,扩展很困难
2、单例模式如果持有Context,容易造成内存泄漏,传getApplacioton Context

猜你喜欢

转载自blog.csdn.net/liu3364575/article/details/80198720