单例模式

单例模式 (Factory Pattern)

创建型模式

涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。
这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

优点:

内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例  
避免对资源的多重占用(比如写文件操作)

缺点:

没有接口,不能继承,与单一职责原则冲突,
只关心内部逻辑,而不关心外面怎么样来实例化。

使用场景:

要求生产唯一序列号。
WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

相关设计模式:

原型模式
单例模式是只有一个实例,原型模式每拷贝一次都会创造一个新的实例。

完整代码地址

/**
 * 双重校验锁
 *  JDK5 或更高版本使用
 *  因为从 JDK5 开始使用新的 JSR-133 内存模型规范,这个规范增强了 volatile 的语义
 * @author wangJiaLun
 * @date 2019-04-15
 **/
public class DoubleCheckLockSingleton {

    // Volatile可以保证可见性和有序性,无法保证原子性
    // 同时保证JVM对指令不会进行重排序

    /**
     *  需要添加 volatile 关键字原因是禁止重排序
     *      instance = new DoubleCheckLockSingleton();
     *  分为三个指令(伪代码)
     *      memory = allocate();        // 1:分配对象的内存空间
     *      ctorInstance(memory);    // 2:初始化对象
     *      instance = memory;        // 3:设置 instance 指向刚分配的内存地址
     * 《The Java Language Specification, Java SE 7 Edition》
     *  规范中定义所有线程执行Java程序时必须遵守intra-thread semantics
     *  保证重排序不会改变单线程内的程序执行结果,所以上述2,3步骤
     *  允许被重排序提供程序执行效率
     *  多线程并发时,如果重排序:
     *      instance对象已经被分配内存地址,未被初始化
     *      其他线程会获取到一个未被初始化的instance
     */
    private volatile static DoubleCheckLockSingleton instance;

    private DoubleCheckLockSingleton(){}

    public static DoubleCheckLockSingleton getInstance(){
        // 判断对象是否已经生成
        // 生成则不进入下面的同步代码
        if (null == instance) {
            synchronized (DoubleCheckLockSingleton.class){
                // 当线程A通过第一层if判断准备进入同步代码时
                // 线程B也通过判断进入同步代码
                // 不加判断线程A&B都会创建新的对象
                if (null == instance) {
                    instance = new DoubleCheckLockSingleton();
                }
            }
        }
        return instance;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

加伦冲呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值