JUC并发编程——单例模式(基于狂神说的学习笔记)

单例模式

饿汉式:

java 复制代码
package single;

// 饿汉式单例
public class hungry {

    // 饿汉式有可能会浪费内存
    // 因为饿汉式在生成对象时,就创建了所有的空间
    // 单例模式构造器私有
    private hungry(){

    }

    private final static hungry HUNGRY = new hungry();
    public static hungry getInstance(){
        return HUNGRY;
    }
}

普通懒汉式:

java 复制代码
package single;

// 懒汉式单例模式
public class lazy {

    // 单例模式构造器私有
    private lazy(){
        System.out.println(Thread.currentThread().getName()+" gotten");
    }

    // 普通懒汉式,在并发下可能会出现问题
    private static lazy lazyMan;
    public static lazy getInstance(){
        if (lazyMan == null){
            lazyMan = new lazy();
        }
        return lazyMan;
    }


    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                lazy.getInstance();
            }).start();
        }
    }

}

使用synchronized与volatile的懒汉式单例

java 复制代码
package single;

// 懒汉式单例模式
public class lazy {
    
    // 单例模式构造器私有
    private lazy(){
        System.out.println(Thread.currentThread().getName()+" gotten");
    }

    // 双重检测锁模式的懒汉式单例
    private volatile static lazy lazyMan;
    private static lazy getInstance(){
        if(lazyMan == null){
            synchronized(lazy.class){
                if (lazyMan == null){
                    lazyMan = new lazy();// 不是一个原子性操作
                    /**
                     * 1、分配内存空间
                     * 2、执行构造方法,初始化对象
                     * 3、把这个对象指向这个空间
                     * 该过程可能发生指令重排
                     * 因此必须让对象加volatile生成内存屏障
                     */
                }
            }
        }
        return lazyMan;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                lazy.getInstance();
            }).start();
        }
    }

}

静态内部类

java 复制代码
package single;

// 静态内部类  (不安全)
public class Holder {

    // 单例模式构造器私有
    private Holder(){

    }
    public static Holder getInstance(){
        return InnerClass.HOLDER;
    }
    public static class InnerClass{
        private static final Holder HOLDER = new Holder();
    }
}

以上单例都不安全,使用反射即可破坏单例

使用枚举单例模式,反射无法破坏枚举单例

相关推荐
潇洒畅想几秒前
1.1 从∑到∫:用循环理解求和与累积
java·数据结构·python·算法
weixin_395772475 分钟前
计算机网络学习笔记】初始网络之网络发展和OSI七层模型
笔记·学习·计算机网络
南境十里·墨染春水21 分钟前
linux学习进展 进程的内存管理
linux·服务器·学习
维齐洛波奇特利(male)22 分钟前
@Pointcut(“execution(* com.hdzx..*(..))“)切入点与aop 导致无限循环
java·开发语言
色空大师23 分钟前
【日志文件配置详解】
java·logback·log4j2·日志
小陈phd27 分钟前
多模态大模型学习笔记(三十四)——ChatTTS:新一代中文语音合成工具原理与实战解析
笔记·学习·语音识别
迷藏49432 分钟前
**发散创新:基于角色与属性的混合权限模型在微服务架构中的实战落地**在现代分布式系统中,
java·python·微服务·云原生·架构
码以致用41 分钟前
Java垃圾回收器笔记
java·jvm·笔记
暴力袋鼠哥42 分钟前
基于springboot与vue的ai多模态数据展示看板
java·spring boot
zhangrelay1 小时前
面向机器人工程的 Linux 发行版:科学选型与深度评测-2026
笔记·学习