你会几种单例模式的写法?

栏目: 后端 · 发布时间: 6年前

内容简介:单例模式经常会是我们学习设计模式的第一个模式。在spring框架下,Bean的默认初始化也是单例模式。 单例模式常见的有懒汉模式和饿汉模式。 先来说说这两个命名由来。 懒汉模式: lazily 饿汉模式: early 感觉是音译。。。一般情况下,单例对象应该是无状态的,也就是说没有成员变量字段,或者说成员变量不发生变化。 而有状态的对象,往往在系统中是多例存在。不同的实例拥有不同的状态。优点: 线程安全,实现简单,容易理解。 缺点: 空间浪费。在启动的时候就会创建实例。

单例模式经常会是我们学习 设计模式 的第一个模式。在spring框架下,Bean的默认初始化也是单例模式。 单例模式常见的有懒汉模式和饿汉模式。 先来说说这两个命名由来。 懒汉模式: lazily 饿汉模式: early 感觉是音译。。。

用途

一般情况下,单例对象应该是无状态的,也就是说没有成员变量字段,或者说成员变量不发生变化。 而有状态的对象,往往在系统中是多例存在。不同的实例拥有不同的状态。

实现方式

饿汉模式

public class Singleton{
    private final static Singleton INSTANCE = new Singleton();
    private Singleton(){}
    public static getInstance(){
        return INSTANCE;
    }
}
复制代码

优点: 线程安全,实现简单,容易理解。 缺点: 空间浪费。在启动的时候就会创建实例。

饿汉模式&代码块

public class Singleton {
    private static Singleton INSTANCE;
    static {
        INSTANCE = new Singleton();
    }
    private Singleton(){}

    public static Singleton getInstance() {
        return INSTANCE;
    }
}
复制代码

这种方式和第一种没有区别。

懒汉模式

public class Singleton {
    private static  Singleton INSTANCE;
    private Singleton(){}
    public static Singleton getInstance(){
        if (INSTANCE == null) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}
复制代码

这种方式实现了懒加载,在调用实例对象的时候才构造。但是带来的问题是线程不安全。如果是在多线程环境下,会生成多个实例。

懒汉模式&同步

public class Singleton {
    private static Singleton INSTANCE;
    private Singleton(){}

    public static synchronized Singleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}
复制代码

要解决线程安全问题,最简单的做法是让方法加个同步。这样一来便可保证线程安全,但是带来的问题是性能损耗。因为其实只有在第一次构造的时候需要同步,以后获取的时候不需要同步的。

懒汉模式&double check

public class Singleton {
    private static Singleton INSTANCE;
    private Singleton(){}

    public static  Singleton getInstance() {
        if (INSTANCE != null) {
            return INSTANCE;
        }
        synchronized (Singleton.class) {
            if (INSTANCE == null) {
                INSTANCE = new Singleton();
            }   
        }
        return INSTANCE;
    }
}
复制代码

这种方式就比较完美了。做一个双重检查,保证了在第一次构造实例的时候的线程安全。同时也保证了之后获取实例对象不需要同步。

懒汉模式&内部类

public class Singleton {
    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton(){}

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}
复制代码

这种方式表面上看和饿汉模式很相似,但是其实也是实现了懒加载。巧妙之处在于利用了内部类启动机制保证了线程安全。个人比较推荐以上两种写法。

枚举用法

public enum Singleton {
    INSTANCE;
}
复制代码

坊间还有使用枚举类来实现的例子,虽然也能达到单例的效果,同时也是线程安全。但是个人并不推崇这种用法,原因在于枚举并不是设计来实现单例的,理解起来会让人困惑。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

连线力

连线力

杨国斌 / 邓燕华 / 广西师范大学出版社 / 2013-9 / 39.00

《连线力》,最关切我们未来的“思想@网络.中国”丛书之一,互联网中国传媒参考书。 中国网民在行动。在中国的广大网民中,普遍存在着对正义的渴望和追求,对弱者和小人物的同情, 对贪官污吏的痛恶,对政府的失望, 对权贵的嘲讽,对沟通的渴望,甚至对革命的呼唤。这些因素有着共同的内在逻辑,即情感逻辑。在这个意义上,情感汹涌的网络事件,是整个中国社会情感结构的脉络。 1994年,中国开通了全功能的......一起来看看 《连线力》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具