单例模式-设计模式

动机

  1. 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。
  2. 如何绕过常规的构造器,提供一种机制来保证一个类只要一个实例?
  3. 这应该是类设计者的责任,而不是使用者的责任。

模式定义

保证一个类仅有一个实例,并提供一个该实例的全局访问点。

类图

在这里插入图片描述

总结

  1. Singleton模式中的实例构造器可以设置为protected已允许子类派生。
  2. Singleton模式一般不要支持拷贝构造函数和Clone接口,因为这有可能导致多个对象实例,与Singleton模式的初衷违背。
  3. 如何实现多线程环境下安全的Singleton?注意对双检查锁的正确实现。

实例

注意点

  • 单例模式需要把构造函数设置为虚函数
  • 需要考虑多线程的问题
  • 使用双检查锁机制
  • 防止指令重排,java中使用volatile关键字
    通常对象的生成包括,实例化、初始化、对象引用赋值,指令重排可能是实例化后直接对象引用赋值了,其实这个时候对象时不可用的。
  1. 单列类
public class HouseSingleton {
    // 添加volatile是为了避免指令重排
    private static volatile HouseSingleton houseSingleton = null;

    private HouseSingleton() {
        System.out.println("Create HouseSingleton");
    }

    public static HouseSingleton getInstance() {
        // 双检查锁机制,可以保证只有实例每创建的时候锁一次,其他情况下都不会锁线程,不会导致性能下降。
        // 问题是,可能出现指令重排,先分配内存然后直接把内存地址赋值给引用变量,导致还没执行构造函数;
        // 因此部分线程不能正常使用实例,因此需要借助volatile关键字避免指令重排。
        if (houseSingleton == null) {
            synchronized (HouseSingleton.class) {
                if (houseSingleton == null) {
                    houseSingleton = new HouseSingleton();
                    return houseSingleton;
                }
            }
        }

        return houseSingleton;
    }

    public void say() {
        System.out.println("Say hello, name:" + Thread.currentThread().getName());
    }
}
  1. 多线程调用单例类
public class Client {
    public static void main(String[] args) throws InterruptedException {

        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(() -> {
                HouseSingleton houseSingleton = HouseSingleton.getInstance();
                houseSingleton.say();
            }, "thread" + (i + 1));

            thread.start();
        }

        Thread.sleep(10000);

    }
}
// 执行结果
Create HouseSingleton
Say hello, name:thread1
Say hello, name:thread2
Say hello, name:thread3
Say hello, name:thread4
Say hello, name:thread86
Say hello, name:thread6
Say hello, name:thread7
Say hello, name:thread8
Say hello, name:thread9
Say hello, name:thread10
Say hello, name:thread11
Say hello, name:thread12
Say hello, name:thread13
Say hello, name:thread14
Say hello, name:thread15
Say hello, name:thread16
Say hello, name:thread18
Say hello, name:thread17
Say hello, name:thread19
Say hello, name:thread20
Say hello, name:thread21
Say hello, name:thread22
Say hello, name:thread23
Say hello, name:thread24
Say hello, name:thread25
Say hello, name:thread26
Say hello, name:thread27
Say hello, name:thread28
Say hello, name:thread29
Say hello, name:thread30
Say hello, name:thread31
Say hello, name:thread32
Say hello, name:thread33
Say hello, name:thread34
Say hello, name:thread35
Say hello, name:thread36
Say hello, name:thread38
Say hello, name:thread39
Say hello, name:thread40
Say hello, name:thread41
Say hello, name:thread42
Say hello, name:thread43
Say hello, name:thread44
Say hello, name:thread99
Say hello, name:thread97
Say hello, name:thread95
Say hello, name:thread100
Say hello, name:thread92
Say hello, name:thread91
Say hello, name:thread37
Say hello, name:thread90
Say hello, name:thread85
Say hello, name:thread84
Say hello, name:thread83
Say hello, name:thread81
Say hello, name:thread79
Say hello, name:thread77
Say hello, name:thread87
Say hello, name:thread76
Say hello, name:thread78
Say hello, name:thread89
Say hello, name:thread74
Say hello, name:thread73
Say hello, name:thread67
Say hello, name:thread65
Say hello, name:thread94
Say hello, name:thread96
Say hello, name:thread64
Say hello, name:thread63
Say hello, name:thread98
Say hello, name:thread62
Say hello, name:thread61
Say hello, name:thread66
Say hello, name:thread60
Say hello, name:thread58
Say hello, name:thread68
Say hello, name:thread56
Say hello, name:thread55
Say hello, name:thread54
Say hello, name:thread52
Say hello, name:thread69
Say hello, name:thread70
Say hello, name:thread71
Say hello, name:thread72
Say hello, name:thread75
Say hello, name:thread80
Say hello, name:thread82
Say hello, name:thread5
Say hello, name:thread88
Say hello, name:thread46
Say hello, name:thread50
Say hello, name:thread45
Say hello, name:thread93
Say hello, name:thread49
Say hello, name:thread48
Say hello, name:thread47
Say hello, name:thread51
Say hello, name:thread53
Say hello, name:thread57
Say hello, name:thread59
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

融极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值