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

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

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

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


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


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


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


1、饿汉模式:



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

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、懒汉模式:



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上锁实现线程安全。

相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
77 2
|
27天前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
3天前
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
2月前
|
Java 调度 开发者
spring的@Scheduled()有几种定时模式?
【10月更文挑战第12天】spring的@Scheduled()有几种定时模式?
130 1
|
2月前
|
设计模式 缓存 Java
面试题:谈谈Spring用到了哪些设计模式?
面试题:谈谈Spring用到了哪些设计模式?
|
3月前
|
设计模式 Java Spring
spring源码设计模式分析(五)-策略模式
spring源码设计模式分析(五)-策略模式
|
3月前
|
消息中间件 设计模式 缓存
spring源码设计模式分析(四)-观察者模式
spring源码设计模式分析(四)-观察者模式
|
3月前
|
设计模式 Java Spring
spring源码设计模式分析(六)-模板方法模式
spring源码设计模式分析(六)-模板方法模式
|
3月前
|
XML Java 开发者
经典面试---spring IOC容器的核心实现原理
作为一名拥有十年研发经验的工程师,对Spring框架尤其是其IOC(Inversion of Control,控制反转)容器的核心实现原理有着深入的理解。
157 3
|
3月前
|
设计模式 Java Spring
spring源码设计模式分析(七)-委派模式
spring源码设计模式分析(七)-委派模式