单例模式(Singleton Pattern)

1 什么是单例模式?

单例模式就是保证运行过程中某个类的实例对象只有一个,例如在 JavaWeb 程序中,service 层的对象其实主要就是提供服务,全局获取一个对象足矣,一般情况下不需要重复定义对象。但是我最初学习的时候也是,在每个 controller 中 new service 层的对象实例,这样会造成资源的浪费;

单例模式属于创造型模式,用于实例化对象。

2 几种单例模式的实现

单例模式的实现有好几种,甚至有大佬列举了 8 种,详细情况如下:
java单例模式------详解JAVA单例模式及8种实现方式_单例模式总结-CSDN博客

个人之前学习的只知道以下几种,真是学无止境啊!

2.1 饿汉单例(线程安全)

直接在类加载的时候就 new 出对象

java 复制代码
package se.wangs.singleton;

/**
 * -- coding: UTF-8 -- *
 *
 * @author wangs
 * @date 2023/12/6 11:23
 * @description 饿汉单例
 */
public class Singleton1 {
    private static final Singleton1 SINGLETON_INSTANCE = new Singleton1();

    private Singleton1() {}
    
    public static Singleton1 getSingletonInstance() {
        return SINGLETON_INSTANCE;
    }
}

2.2 饿汉单例(线程不安全)

当多个线程同时访问可能会进入 if 语句,造成实例化多个实例;

java 复制代码
package se.wangs.singleton;

/**
 * -- coding: UTF-8 -- *
 *
 * @author wangs
 * @date 2023/12/6 11:27
 * @description 懒汉单例(线程不安全1)
 */
public class Singleton2 {
    private static Singleton2 singletonInstance;
    
    private Singleton2() {}
    
    private static Singleton2 getSingletonInstance() {
        if (singletonInstance == null) {
            singletonInstance = new Singleton2();
        }
        return singletonInstance;
    }
}

2.3 懒汉单例(锁方法)

这种方式是线程安全的,但是直接锁住方法的线程较低

java 复制代码
package se.wangs.singleton;

/**
 * -- coding: UTF-8 -- *
 *
 * @author wangs
 * @date 2023/12/6 11:27
 * @description 懒汉单例(锁方法)
 */
public class Singleton3 {
    private static Singleton3 singletonInstance;

    private Singleton3() {}

    private static synchronized Singleton3 getSingletonInstance() {
        if (singletonInstance == null) {
            singletonInstance = new Singleton3();
        }
        return singletonInstance;
    }
}

2.4 懒汉单例(双重检查)

线程安全

java 复制代码
package se.wangs.singleton;

/**
 * -- coding: UTF-8 -- *
 *
 * @author wangs
 * @date 2023/12/6 11:33
 * @description 饿汉单例(双重检查)
 */
public class Singleton4 {
    private volatile static Singleton4 singletonInstance;

    private Singleton4() {}

    private static synchronized Singleton4 getSingletonInstance() {
        if (singletonInstance == null) {
            synchronized (Singleton4.class) {
                if (singletonInstance == null) {
                    singletonInstance = new Singleton4();
                }
            }
        }
        return singletonInstance;
    }
}

3 总结

3.1 单例模式的关键

(1)私有化构造器:使得该类只能在内部实例化,外部不能实例化;

(2)保证内部能实例化出一个对象,并且仅实例化一次;

(3)考虑线程安全,需要注意加锁;

3.2 volatile 关键字

参考大佬博客
Java并发常见面试题总结(中)

该关键字可以保证可见性,修饰的变量,在每次访问的时候,都要去内存中获取最新的值

3.3 单例模式在 Spring 中的应用

spring 中 bean 的管理默认是使用的单例模式,即 scope 属性默认是 "scope=singleton"

相关推荐
FogLetter10 分钟前
设计模式奇幻漂流:从单例孤岛到工厂流水线
前端·设计模式
guangzan4 小时前
常用设计模式:代理模式
设计模式
西幻凌云6 小时前
认识设计模式——单例模式
c++·单例模式·设计模式·线程安全·饿汉和懒汉
爱吃烤鸡翅的酸菜鱼7 小时前
【Java】基于策略模式 + 工厂模式多设计模式下:重构租房系统核心之城市房源列表缓存与高性能筛选
java·redis·后端·缓存·设计模式·重构·策略模式
在未来等你15 小时前
AI Agent设计模式 Day 5:Reflexion模式:自我反思与持续改进
设计模式·llm·react·ai agent·plan-and-execute
程序员三藏15 小时前
快速弄懂POM设计模式
自动化测试·软件测试·python·selenium·测试工具·设计模式·职场和发展
Lei_33596716 小时前
[設計模式]設計模式的作用
设计模式
将编程培养成爱好17 小时前
C++ 设计模式《统计辅助功能》
开发语言·c++·设计模式·访问者模式
乙己4071 天前
设计模式——桥接模式(bridge)
设计模式·桥接模式
WKP94181 天前
原型设计模式
java·设计模式