前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官:spring单例模式,多例模式,饿汉模式,懒汉模式(二)?

面试官:spring单例模式,多例模式,饿汉模式,懒汉模式(二)?

作者头像
用户9919783
发布2022-07-26 11:32:43
3800
发布2022-07-26 11:32:43
举报
文章被收录于专栏:后端从入门到精通

上篇文章介绍了单例模式,多例模式,有不明白的同学可以点进去先观看:

面试官:spring单例模式,多例模式,懒汉模式,饿汉模式(一)?

这篇文章重点介绍饿汉模式懒汉模式,

饿汉模式:在加载对象时候,对象就会创建实例,为所有spring配置文件中定义的bean都是生成的一个实例,天生线程安全的,多线程的情况下也不会出现问题。

懒汉模式:在获取对象第一次请求的时候,才会创建实例。本身是线程不安全的,但有几种实现线程安全的写法。

1、饿汉模式:

因为实例被static和final修饰,在对象加载到内存的时候初始化,所以线程安全。

代码语言:javascript
复制
public class HungrySingleton {

    private String name;

    private static final HungrySingleton hungrySingleton = new HungrySingleton("张三");

    public HungrySingleton(String name){
        this.name = name;
    }

    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }

}

虽然这样写线程安全,但他还是有缺陷的,在getBean实例之前,不能不给他设置属性和参数,这时候懒汉模式就出现了,可以通过双重检索可以实现线程安全。

2、懒汉模式:

代码语言:javascript
复制
 private String name;
    private static LazySingleton lazySingleton;

    public LazySingleton(String name) {
        this.name = name;
    }

    public static LazySingleton getInstance() {
        //第一次访问的时候没有对象,所以获取对象
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton("张三");
        }
        return lazySingleton;
    }

    public static LazySingleton getInstance2() {
        //保证线程安全
        synchronized (lazySingleton) {
            if (lazySingleton == null) {
                lazySingleton = new LazySingleton("张三");
            }
        }
        return lazySingleton;
    }

    public static LazySingleton getInstance3() {
        //保证线程安全,性能提升
        if (lazySingleton == null) {
            synchronized (lazySingleton) {
                if (lazySingleton == null) {
                    lazySingleton = new LazySingleton("张三");
                }
            }
        }
        return lazySingleton;
    }

懒汉模式可以通过双重效验和synchronized来实现线程安全

问:为什么要双重效验?从代码里我们可以看到

getInstance()方法可以实现,第一次访问的时候没有对象,所以为null的时候,获取实例对象,但这种情况下多线程访问时候,会出现异常,导致创建多个实例,如何解决呢?

getInstance2()方法可以保证线程安全,上锁之后,其他线程不可以进入,但这种情况会出现什么问题呢?会一直上锁,导致没必要的性能开销,实际只需要在第一次创建的上锁。

getInstance3()这就是为什么要用双重效验,先判断是否为null,然后在用synchronized上锁实现线程安全。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后端从入门到精通 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档