美文网首页
单例模式的实现方法及它们的优缺点

单例模式的实现方法及它们的优缺点

作者: DH大黄 | 来源:发表于2020-01-09 23:52 被阅读0次

本文是学习悟空老师的视频教程线程八大核心基础后所做的心得笔记,想更加具体了解其中知识的小伙伴可以前往慕课网悟空老师的课程中进行学习

单例模式的八种实现方式

单例模式(实现方式).png

红色为重点内容,方法3,5为线程不安全写法,不可用

参考资料来源:慕课网八大核心线程基础


方法的具体实现代码

1.饿汉式(静态常量)
package singleton;

/**
 * 饿汉式(静态常量)(可用)
 * 类加载时就进行实例的初始化
 */
public class Singleton1 {

    private final static Singleton1 INSTANCE = new Singleton1();

    private Singleton1() {

    }

    public static Singleton1 getInstance() {
        return INSTANCE;
    }

}
2.饿汉式(静态代码块)
/**
 * 饿汉式(静态代码块)(可用)
 * 同样也是在类加载时便初始化实例
 */
public class Singleton2 {

    private final static Singleton2 INSTANCE;

    static {
        INSTANCE = new Singleton2();
    }

    private Singleton2() {
    }

    public static Singleton2 getInstance() {
        return INSTANCE;
    }
}

——————————饿汉式一个需要注意的情况——————————

饿汉式如果对象的实例化需要读取配置文件的话,饿汉式便不适用了

———————————————end———————————————

3.懒汉式(线程不安全的写法)(该方法不可用)
/**
 * 懒汉式(线程不安全)
 */
public class Singleton3 {

    private static Singleton3 instance;

    private Singleton3() {

    }

    public static Singleton3 getInstance() {
        // 不安全原因在这里(当两个线程同时进入的时候,发现instance都为null,便会实例化两个对象)
        // 与单例的初衷不符合
        if (instance == null) {
            instance = new Singleton3();
        }
        return instance;
    }
}
4.懒汉式(线程安全,同步方法)(可以用但不推荐使用,原因:性能较低)
/**
 * 描述:     懒汉式(线程安全)(不推荐)
 */
public class Singleton4 {

    private static Singleton4 instance;

    private Singleton4() {

    }

    /**
     * 给getInstance()方法加入synchronized关键字,成为了同步方法
     * 每次get都要获取锁,代码性能较低,不推荐使用
     */
    public synchronized static Singleton4 getInstance() {
        if (instance == null) {
            instance = new Singleton4();
        }
        return instance;
    }
}
5.懒汉式(线程不安全,同步代码块)(不能使用)
/**
 * 懒汉式(线程不安全)(不推荐)
 */
public class Singleton5 {

    private static Singleton5 instance;

    private Singleton5() {

    }

    public static Singleton5 getInstance() {
        if (instance == null) {
            // 对新建实例这行代码增加同步代码块
            // 两个线程同时执行到这一句,第一个线程抢占锁,新建了一个实例并释放锁
            // 第二个线程抢占第一个线程释放的锁之后,也新建了一个实例
            // 这样的话,便会新建两个实例(与单例的初衷相违背)
            synchronized (Singleton5.class) {
                instance = new Singleton5();
            }
        }
        return instance;
    }
}
6.双重检查(推荐使用,面试重点之一)
/**
 * 双重检查
 */
public class Singleton6 {

    private volatile static Singleton6 instance;

    private Singleton6() {

    }

    public static Singleton6 getInstance() {
        if (instance == null) {
            synchronized (Singleton6.class) {
                if (instance == null) {
                    instance = new Singleton6();
                }
            }
        }
        return instance;
    }
}

———————————————双重检查常见问题—————————————

  1. 首先先陈述下它的优点(线程安全,延迟加载,效率较高)

    (它与4,5两种方法比较,4存在性能问题,5存在线程安全问题)

  2. 为什么要双重检查(这与5为什么会存在线程安全问题是一样的考虑情况)

  3. 为什么需要volatile关键字

    原因:instance = new Singleton6(); 这一步操作不是原子性操作

    该操作主要分为以下三步(这三步可能因为jvm虚拟机的原因,会发生重排序)

    1. 创建一个空对象
    2. 调用构造方法
    3. 赋值

    当发生重排序的时候,线程1先给instance赋值,但没有调用构造方法给对象初始化

    对象里面的参数都没有赋予内容

    此时CPU将资源从线程1切换给线程2,

    线程2进入,发现instance不为null,便默认为instance已经初始化完毕,

    但是当线程2执行方法要使用instance里面的参数的时候,便会报空指针错误

    所以要使用volatile关键字来禁止重排序

—————————————————end—————————————————

7.静态内部类(可用,也是属于懒汉模式)(当jvm加载时,只会加载外部类,不会加载内部类)
/**
 * 静态内部类方式,可用
 */
public class Singleton7 {

    private Singleton7() {
    }

    private static class SingletonInstance {

        private static final Singleton7 INSTANCE = new Singleton7();
    }

    public static Singleton7 getInstance() {
        return SingletonInstance.INSTANCE;
    }
}
8.枚举类(推荐在日常工作中使用)(大佬推荐!)
/**
 * 枚举单例
 */
public enum Singleton8 {
    INSTANCE;

    public void whatever() {

    }
}

优点:写法简单,线程安全有保障,同时还避免反序列化(反射)破坏单例

相关文章

  • 单例模式的实现方法及它们的优缺点

    本文是学习悟空老师的视频教程线程八大核心基础后所做的心得笔记,想更加具体了解其中知识的小伙伴可以前往慕课网悟空老师...

  • 单例模式的常用实现方式

    单例模式属于最常用的设计模式,Java中有很多实现单例模式的方式,各有其优缺点 实现方式对比 单例实现方式线程安全...

  • 单例模式

    单例模式及C++实现代码单例模式4种实现详解 c++11改进我们的模式之改进单例模式 单例模式(Singleton...

  • python面试题-2018.1.30

    问题:如何实现单例模式? 通过new方法来实现单例模式。 变体: 通过装饰器来实现单例模式 通过元类来创建单例模式...

  • 2018-06-19 Python中的单例模式的几种实现方式的及

    转载自: Python中的单例模式的几种实现方式的及优化 单例模式 单例模式(Singleton Pattern)...

  • 单例模式只有饿汉式和懒汉式吗?这几种单例模式你见过吗

    设计模式之单例模式-单例模式的几种实现方式及小案例 本文出处:凯哥Java(wx:kaigejava) 单例模式有...

  • 单例模式

    1.利用装饰器实现单例模式 2.修改new方法实现单例模式 3.利用元类实现单例模式 总结: 用装饰器和元类实现的...

  • 单例模式(单例宏)

    单例模式 单例模式(arc) 类的实现 调用单例 单例模式(mrc) 除了上边的方法我们在mrc的时候还需要增加一...

  • iOS面试题系列之Objective-C相关

    1、简述你项目中常用的设计模式。它们有什么优缺点?常用的设计模式有:代理、观察者、单例。(1)单例:它是用来限制一...

  • Python之单例模式总结

    一、单例模式 a、单例模式分为四种:文件,类,基于__new__方法实现单例模式,基于metaclass方式实...

网友评论

      本文标题:单例模式的实现方法及它们的优缺点

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