美文网首页
单例模式

单例模式

作者: 海是倒过来的天_67f2 | 来源:发表于2018-08-08 10:57 被阅读0次

    单利模式的核心结构中包含一个被称为单利的特殊类,通过单例模式可以保证系统中,应用该模式的 类只有一个实例对象。

    1.单利模式的优缺点;

    优点:系统中该类的对象的实例只有一个,节省了系统资源,对于一些需要频繁创建和销毁的对象,使用单利模式可以提高系统性能。

    缺点:要想实例化单例时,必须要记住获取对象的方法,而不是使用new方法,可能会给开发者带来困扰

    2.适用场所:

    需要频繁的创建和销毁对象

    创建对象时耗时过多或消耗资源过多,又经常使用到的对象。

    工具栏对象

    频繁访问数据库或者文件的对象。

    3.单利模式分为两种懒汉模式和恶汉模式

    懒汉模式:在类初始化的时候不进行初始化

    恶汉模式:在类加载完的时候就完成了初始化,所有类一块加载,加载速度较慢,但是获取对象速度较快。

    1.恶汉模式(静态常量)

    public class SingleMode{

    private final static SingleMode INSTANCE = new SingleMode();

    private SingleMode(){}

    public static  SingleMode getInstance(){

    return INSTANCE;

    }

    }

    优点:写法比较简单,在类加载的时候就完成了创建,避免了线程同步的问题

    缺点:在类加载的时候就完成了创建,没有达到懒加载的目的,如果至始至终没有使用过这个实例,会造成资源浪费。

    2恶汉模式(静态代码块)

    public class SingleMode{

    private static SingleMode sInstance;

    static {

    sInstance = new SingleMode()

    }

    public static SingleMode getInstance(){

    return sInstance;

    }

    }

    几乎和方法1一样,只不过是将实例化的过程放在了静态代码块中,也是在类加载的时候就执行了静态代码块中的数据,优缺点和方法1一样。

    3.懒汉模式(线程不安全)

    public class SingleMode(){

    private static SingleMode instance;

    private SingleMode(){}

    public static  SingleMode getInstance(){

    if(instace == null){

    instance = new SingleMode;

    }

    return instance;

    }

    }

    一般只在单线程中使用,如果在多线程中使用可能会产生多个实例,因此不采用。

    4.懒汉模式(线程安全)

    public class SingleMode{

    private SingleMode instance;

    private SingleMode(){}

    public static synchronized SingleMode getInstance(){

    if(instance == null){

    instance = new Singlemode();

    }

    return instance;

    }

    }

    解决了线程不安全的问题,但是每个线程想要获得类的实例时,都需要调用getInstance()方法进行同步,效率太低。

    5.懒汉模式(线程安全,同步代码块,不在同步整个方法)

    public class SingleMode{

    private SingleMode sInstance;

    private SingleMode(){}

    public static SingleMode getInstance(){

    if(sInstance == null){

    synchronized(this){

    sInstance = new SingleMode();

    }

    }

    return sInstance;

    }

    }

    这种方式看是方法四的优化,其实不然,这种方式和第三种一样,并不能保证线程安全,例如一个线程进入了if(sInstance == null)判断语句,还未来得及创建实例,此时另外一个线程也通过了这个判断语句,此时就会产生多个实例。

    6.懒汉模式双重检查(线程安全)

    public class SingleMode{

    private static SingleMode sInstance;

    private SingleMode(){}

    public static SingleMode getInstance(){

    if(sInstance == null){

    synchronized(this){

    if(sInstance == null){

    sInstance = new SingleMode();

    }

    }

    }

    return sInstance;

    }

    }

    双重检查在多线程中很常见,在代码中,进行了两次if(sInstance == null)的检查,这样就可以保证了线程安全

    优点:线程安全,延迟加载,效率较高

    7.静态内部类

    public class SingleMode{

    private SingleMode(){}

    private static class SingleHolder{

    private static final SingleMode INSTANCE = new SingleMode();

    }

    public static SingleMode getInstance(){

    reruen  SingleHolder.INSTANCE;

    }

    }

    静态内部类的实现方式和恶汉模式采用的机制类似,但是又有所不同,两者都采用了类加载的机制来保证初始化时,只有一个线程。不同的地方在于恶汉模式只要SingleMode类被加载就会初始化,没有懒加载的作用,而静态内部类在SingleMode类被加载时不会立即实例化。而是在需要实例化的时候才会调用getInstance,从而加载SingleHolder类,完成SingleMode的实例化。

    优点,避免了线程不安全,延迟加载,效率高

    8.枚举

    public enum SingleMode{

    INSTANCE;

    public void whateverMethod(){

    }

    }

    JDK1.5以后才出现的单例模式,不仅能避免多线程问题而且还能防止反序列化重新创建新的对象。项目中很少用到。

    相关文章

      网友评论

          本文标题:单例模式

          本文链接:https://www.haomeiwen.com/subject/yjutbftx.html