单列模式

1、什么是单列模式

单列模式(Singleton)保证一个类仅有一个实例,并提供一个访问的全局访问点,这种类型的设计模式属于创建型模式。在开发中,会经常遇到一个全局使用的类频繁地创建与销毁,这会非常浪费系统的内存资源,而且容易导致错误甚至一定会产生错误,所以我们单例模式所期待的目标或者说使用它的目的,是为了尽可能的节约内存空间,减少无谓的GC消耗,并且使应用可以正常运作。


结构图

2、实现方式

2.1、懒汉模式,线程不安全

最基本的实现方式,这种实现最大的问题就是不支持多线程。

public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

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

针对懒汉模式线程不安全的问题,我们自然想到了,在getInstance()方法前加锁,于是就有了第二种实现

2.2、懒汉模式,线程安全

能够在多线程中很好的工作,打补丁方式写出来的结构效率很低,多数情况下不需要同步。

public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

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

因为加了synchronized为独占排他锁,并发性能差,于是为了解决这个问题又有第三种实现

2.3、饿汉式

在类加载的时候,就完成了对象的初始化,类加载保证了他们天生是线程安全的

public class Singleton {

    private static Singleton instance = new Singleton();

    private Singleton() {

    }

    public static Singleton getInstance() {
        return instance;
    }
}

没有达到Lazy Loading的效果,如果从始至终从未使用过这个实例,则会造成内存的浪费,那如何解决这个问题呢?

2.4、静态内部类

Singleton 类被装载了,instance 不一定被初始化,只有在调用的时候才进行加载,达到了类似懒汉模式的效果,而这种方法又是线程安全的。

public class Singleton {

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

2.5、枚举

枚举实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化和线程安全的

public enum Singleton {

    INSTANCE;

    public void action() {

    }
}
调用
Singleton.INSTANCE.action();

2.6、双重校验锁法

采用双锁机制,安全且在多线程情况下能保持高性能

public class Singleton {

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

3、总结

推荐使用3-6的实现方式,当然并不是说1-2不能使用,具体的还需要根据业务场景来使用,例如不需要再多线程使用的可以根据1来实现;需要支持序列化的可以使用5来实现,一般情况下建议使用3来实现

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,591评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,141评论 1 32
  • 单例模式(SingletonPattern)一般被认为是最简单、最易理解的设计模式,也因为它的简洁易懂,是项目中最...
    成热了阅读 4,292评论 4 34
  • 炼狱狂歌 作者/胄宁 映着血色的炼狱里埋葬了最倔强的躯体,无法抹去,那绯红的印记。 而你在炼狱的中央,唱着那空荡绝...
    胄宁阅读 443评论 1 4
  • 不知道大家像我一样,每次睡觉前,总感觉脑海中有很多想法……或许是后悔今天的决定,或许是憧憬明天的未来,再或...
    公子在此阅读 267评论 0 0