JAVA设计模式大总结(二)-- 单例模式(八种玩法 代码实现+详解)

主题:最常见的设计模式之一:单例模式
简单say一下概念:
在这里插入图片描述
声明一点:为了节约时间,做到简洁干练,本文章参考了b站的尚硅谷所分享的教学资源

废话不多说直接撸码开干:
(一)饿汉模式:静态常量

/*
   饿汉式(静态常量)
 */
public class SingleOne {
    private final static SingleOne instance = new SingleOne();
    private SingleOne(){}
    public static SingleOne getInstance(){
        return instance;
    }

}

测试用例:

        SingleOne singleOne1 = SingleOne.getInstance();
        SingleOne singleOne2 = SingleOne.getInstance();
        System.out.println(singleOne1 == singleOne2);
        System.out.println("SingleOne1的hashcode== "+singleOne1.hashCode());
        System.out.println("SingleOne2的hashcode== "+singleOne2.hashCode());

运行结果:说明只获得到一个实例,后面的测试用例都以此形式
在这里插入图片描述
优缺点分析:
在这里插入图片描述
(二)饿汉式:静态代码块

public class SingleTwo {
    private final static SingleTwo instance;
    private SingleTwo(){}
    static {
        instance = new SingleTwo();
    }
    public static SingleTwo getInstance(){
        return instance;
    }

}

优缺点与(一)一样,俩段代码十分相似

(三)懒汉式(线程不安全)

/*
  懒汉式--线程不安全
 */
public class SingleThree {
    private static SingleThree instance;
    private SingleThree(){}
    public static SingleThree getInstance(){
        if(instance == null){
            instance = new SingleThree();
        }
        return instance;
    }

}

优缺点分析:
在这里插入图片描述
(四)懒汉式(线程安全)

public class SingleFour {

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

}

优缺点分析:
在这里插入图片描述
(五)懒汉式–错误玩法例子
在这里插入图片描述
分析:
在这里插入图片描述

(六)双重检查:

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

}

在这里插入图片描述
变量的关键字volatile非常重要
volatile作用:以下会涉及到Java内存模型的知识

禁止指令重排序。我们知道new Singleton()是一个非原子操作,编译器可能会重排序【构造函数可能在整个对象初始化完成前执行完毕,即赋值操作(只是在内存中开辟一片存储区域后直接返回内存的引用)在初始化对象前完成】。而线程B在线程A赋值完时判断instance就不为null了,此时B拿到的将是一个没有初始化完成的半成品。

保证可见性。线程A在自己的工作线程内创建了实例,但此时还未同步到主存中;此时线程B在主存中判断instance还是null,那么线程B又将在自己的工作线程中创建一个实例,这样就创建了多个实例。

声明:volatile参考了
https://blog.csdn.net/zcl_love_wx/article/details/80758162

(七)枚举实现单例类:(有大佬非常推荐)

public enum SingleSeven {
    Instance;
    public void method(){
        System.out.println("hello world");
    }
}

在这里插入图片描述
(八)静态内部类实现单例类:

public class SingleEight {

    private SingleEight(){}
    private static class Single{
        private final static SingleEight INSTANCE = new SingleEight();
    }
    private static SingleEight getInstance(){
        return Single.INSTANCE;
    }
}

优缺点分析:
在这里插入图片描述
总结:红色的推荐在开发中推荐使用
在这里插入图片描述

本文章可以说是站在巨人的肩膀中对知识的总结,方便自己日后的回顾,十分感谢尚硅谷以及广大博友的资源共享。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值