【谈一谈】: 我们工作中的单例模式有哪些写法?

这篇具有很好参考价值的文章主要介绍了【谈一谈】: 我们工作中的单例模式有哪些写法?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单例模式的多种写法

我们要实现一个单例,首先最重要的是什么?

当然是把构造函数私有化,变成private类型,(为啥? 单例单例,如果谁都能通过构造函数创建对象,还叫单例吗?是不~)

嗯~我们构造函数私有化后,我们应该操作啥呢?

接着我们需要提供一个方法,这个方法要保证初始化有且仅初始化一个单例对象!~

Okk~,请再看看我们的标题,思考下,单例模式有哪几种写法呢?工作中我们最常用的是哪些呢?

好了,别想了,我们一起看答案

单例模式有五种模式: 1.懒汉,2.饿汉,3.枚举,4.静态内部类,5.双重检验锁

最常用的嘛: 当然两个单身汉啦: 饿汉懒汉了(和我一样,都是狗~哈哈哈)


上述的说明是我们对单例模式整体有了个大概得了解,你说:这不行啊!我还是*心虚*,因为只是**纸上谈兵**,别急嘛,我们这就**此事躬行**!


万变不离其宗:

本文总纲图:

【谈一谈】: 我们工作中的单例模式有哪些写法?,工作总结,笔记,单例模式,javascript,开发语言

下面是五中单例模式的代码实现,(还是那句话~看不懂,我们就敲,若一遍不行,就两遍,Practice makes perfect!)

还有在敲下面的代码之前,我们思考下(也是一道面试题)

为啥单例模式要使用staticfinal进行声明呢???(后面我会给解答,但先思考下,会吸收事半功倍~哈哈哈)

1.懒汉模式

为啥叫懒汉模式呢?如它的名字一样,创建对象只有进程用到的时候,才进行创建

换句话说: 被动创建,比如工作,老板叫我干我就做,没叫我时,我就佛系摸鱼

具体代码:

package com.design_patterns;
/**
 * <p>
 * 描述:  懒汉单例$      <br>
 * <p>
 * 需求信息: 【需求ID与需求标题】【客户名称】 <br>
 *
 * @author aristo
 * @date 2024/2/21 10:51
 */
public class LazyMan {
    public  static  LazyMan instance;   
    //构造函数私有化
    private LazyMan(){};
    //获取对象
    public  static synchronized LazyMan getInstance(){
        //发现对象为空时,创建对象;否则直接返回
        if(instance==null){
            instance=new LazyMan();
        }
        return instance;
    }
}

2.饿汉模式

此模式就和懒汉就相反了,有种忧患意识,类似悲观锁的算法设计思想

啥意思?就是在程序启动时,我就立即将单例对象给创建出来—具体我们看代码就一幕了然了

package com.design_patterns;
/**
 * <p>
 * 描述:  饿汉模式$      <br>
 * <p>
 * @author zf
 * @date 2024/2/21 14:31
 */
public class HungryModel {
    //注意看: 我们这里是直接就创建对象了   这里面的static和final思考下为啥用(不用行不行呢?)
    public  static  final   HungryModel instance=new HungryModel();
    private   HungryModel  (){};
    public  static  HungryModel getInstance(){
        //这里我们就直接返回
        return instance;
    }
}

3.枚举单例模式

写到枚举单例模式,我们在这也思考一道题目:

为什么枚举是最好的单例模式?? (哈哈哈!你别吐槽–这博主真是的,我就看个博文,咋又叫我思考噻!没错,因为我们要的是看一篇顶三篇!!!)

这我会单独写一篇文章描述,这里插个眼,标记下~哈哈哈

代码实现示例:

package com.design_patterns;

/**
 * 描述:  单例模式---枚举方式      <br>
 * @author zf
 * @date 2024/2/21 16:14
 */
public enum EnumSingleton {
    INSTANCE;
    public void  testMethod(){

    }
}

4.静态内部类单例模式

所谓的静态内部类单例模式,我们可以看到在创建对象时,我们是在类中定义一个静态内部类(很关键!!!) 其实你自己敲一遍就拨开其真面目了!~

详细解说嘛,我推荐你敲一遍,就知庐山真面目了~(你说,那我敲一遍还不懂咋整啊?直接评论区@轰炸我)

package com.design_patterns;

/**
 * 描述:  静态内部类单例模式      <br>
 * @author zf
 * @date 2024/2/21 16:18
 */
public class StaticInnerClassSingleton {
    //所谓的静态内部类单例模式,我们可以看到在创建对象时,我们是在类中定义一个静态内部类(很关键!!!!)   其实你自己敲一遍就拨开其真面目了!~
    private static class SingletonHolder{
        private static final StaticInnerClassSingleton INSTANCE=new StaticInnerClassSingleton();
    }
    private StaticInnerClassSingleton(){};
    public static final StaticInnerClassSingleton getInstance(){
        return SingletonHolder.INSTANCE;
    }

}

5.双重检验锁单例模式

顾名思义: 就是通过两把锁检测把关后,我们创建对象,啥好处?安全性高

对于代码中的volatile,再思考一下,我们为啥要加??

package com.design_patterns;

/**
 * <p>
 * 描述:  双重检验锁单例模式      <br>
 * <p>
 * 需求信息: 【需求ID与需求标题】【客户名称】 <br>
 *
 * @author zf
 * @date 2024/2/21 16:29
 */
public class DoubleLockSingleton {
    //好了,别想了,我解答下: 使用volatile:  防止指令重排!!!!!(面试官问你,就抛给他这句话,完事~)
    private volatile static DoubleLockSingleton doubleLockSingleton;
    //私有化
    private DoubleLockSingleton(){};
    public static DoubleLockSingleton getInstance(){
        //第一遍检验
        if(doubleLockSingleton==null){
            synchronized (DoubleLockSingleton.class){
                //再次检验
                if(doubleLockSingleton==null){
                    doubleLockSingleton=new DoubleLockSingleton();
                }
            }
        }
        return doubleLockSingleton;
    }
}

【解答】单例模式为啥使用static和final关键字???

回顾我们一开始说的问题,我来解答下哈!耐心看看嘛,绝对夯实基础,出门还可**吹牛逼**!嘿嘿

1.static的特殊含义

static可以保证在一个线程未使用其他同步机制的情况下总是可以读到一个类的静态变量的初始值!!!(这句话建议读三遍,真的诠释了静态的真谛)

上面也许不好理解,但我们首先应该知道:static变量是随着类被初次访问而初始化的。

比如在多线程的环境中,需要保证一个变量在线程中的可见性是需要对内存做一些操作指令的。

这么说不怎么明白吧? 举个例子:(可以不看哈,纯粹为了加深理解)

当两个线程A,B对一个共享变量进行操作的时候,

  • 首先是把内存中的数据加载进各自的处理器中,然后在放入各自的寄存器
  • A中更新共享变量的时候,首先会被放入写缓存器中,然后再写入高速缓存中,最后是放进内存中,每个处理器都有各自的写缓存器高速缓存
  • 所以在一个时间点,线程B读取的共享变量值并不是A更新的那一个,仍然很有可能是一个旧值。(类似于脏读)
  • 对于这个旧值怎么理解呢?()
    • 在计算机系统设计中,为了保证变量的可见性,有一种协议叫做缓存一致性协议
    • 这个协议的作用我简单说明下:不同的处理器可以读取对方高速缓存中的值。这时我们要保证可见性只需要一步,就是当共享变量被更新的时候,原子性保证把值写入高速缓存中就可以了,
    • 对于volatile的实现方式也是基于这种思想。
  • 那么static变量所做的事情就是,在某个线程调用的时候,就写入内存中这个值,保证内存中必然有这个值的存在,
  • 注意static并不能保证多线程之后操作的可见性

2.final

我们都知道,final修饰的变量值不会改变;但是在多线程的环境中,它还会保证两点

  1. 其他线程所看到的final字段必然是初始化完毕的。
  2. final修饰的变量不会被程序重排序。

综上所述:

static保证了变量的初始值,final保证了不被JIT编译器重排序。

对于一个单例模式来说,它所在的类在被引用的时候,static会保证它被初始化完毕,且是所有线程所见的初始化final保证了实例初始化过程的顺寻性。两者结合保证了这个实例创建的唯一性。

完结

好了,各位优秀的同仁们,学废了没?哈哈哈!~是不是又学到了呢?文章来源地址https://www.toymoban.com/news/detail-834029.html

到了这里,关于【谈一谈】: 我们工作中的单例模式有哪些写法?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 谈一谈浏览器与Node.js中的JavaScript事件循环,宏任务与微任务机制

    JavaScript是一个单线程非阻塞的脚本语言。这代表代码是执行在一个主线程上面的。但是JavaScript中有很多耗时的异步操作,例如AJAX,setTimeout等等;也有很多事件,例如用户触发的点击事件,鼠标事件等等。这些异步操作并不会阻塞我们代码的执行。例如: 可以看到,上述代

    2024年02月12日
    浏览(48)
  • 【单例模式】饿汉模式和懒汉模式的单例模式

    设计模式是一种 在软件设计中经过验证的解决问题的方案或者模版 。它们是从实践中总结出来的,可以帮助解决常见的设计问题,提高代码的重用性、维护性和扩展性。 设计模式可以分为三大类: 创建型模式(Creational Patterns) :创建型模式关注对象的实例化过程,包括如

    2024年02月16日
    浏览(66)
  • 委托的单例模式

     在项目中我们经常会使用到委托,委托是多播的,如果控制不好反复注册就会多次触发,可以使用委托的单例模式去注册,这样可以避免多次触发问题。 下面是几种委托实例代码: 带参数委托管理: 调用方法: ActionManager参数.Removal(\\\" 注册Key \\\"); ActionManager 参数 .Register(\\\" 注册

    2024年02月08日
    浏览(54)
  • C++的单例模式

    忘记之前有没有写过单例模式了。 再记录一下: 我使用的代码: 双锁单例: 单例模式的不同实现方式各有优缺点 双检锁(Double Checked Locking): 优点: 线程安全。 在实例已经被创建之后,直接返回实例,避免了每次获取实例时都需要获取锁的开销。 缺点: 代码相对复杂

    2024年02月10日
    浏览(46)
  • 设计模式系列:经典的单例模式

    单例模式,是设计模式当中非常重要的一种,在面试中也常常被考察到。 正文如下: 一、什么时候使用单例模式? 单例模式可谓是23种设计模式中最简单、最常见的设计模式了,它可以保证一个类只有一个实例。我们平时网购时用的购物车,就是单例模式的一个例子。想一

    2024年02月15日
    浏览(44)
  • 谈一谈redis脑裂

    (1)一主多从架构中,主节点与客户端通信正常,主节点与哨兵、从节点连接异常,客户端仍正常写入数据 (2)哨兵判定主节点下线,重新选主 (3)原主节点与哨兵和其他节点通信恢复,成为新主节点的从节点,drop本身所有的数据,从新主节点全量copy数据 (4)原主节点

    2024年02月12日
    浏览(47)
  • 谈一谈接口测试

    我相信你一定听说过这样一句话:“测试要尽早介入,测试进行得越早,软件开发的成本就越低,就越能更好地保证软件质量。” 但是如何尽早地进入测试,作为软件测试的你,是不是也没办法说得清楚呢?其实上面那句话中的“测试”,所指的并不是测试这个人,而是指包

    2024年02月08日
    浏览(52)
  • 【多线程】线程安全的单例模式

    单例模式能保证某个类在程序中只存在 唯一 一份实例, 而不会创建出多个实例,从而节约了资源并实现数据共享。 比如 JDBC 中的 DataSource 实例就只需要一个. 单例模式具体的实现方式, 分成 “饿汉” 和 “懒汉” 两种. 类加载的同时, 创建实例. 注意: 使用 static 修饰 instanc

    2024年02月09日
    浏览(44)
  • kotlin实现java的单例模式

    Kotlin的5种单例模式

    2024年02月10日
    浏览(36)
  • 谈一谈扫码登录原理

      今天给大家介绍下扫码登录功能是怎么设计的。 扫码登录功能主要分为三个阶段: 待扫描、已扫描待确认、已确认 。 整体流程图如图。 下面分阶段来看看设计原理。 1、待扫描阶段 首先是待扫描阶段,这个阶段是 PC 端跟服务端的交互过程。 每次用户打开PC端登陆请求,

    2024年02月10日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包