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();
    }
}

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

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

相关推荐
蝎子莱莱爱打怪21 分钟前
别再裸用 Claude Code 了!32 个亲测Skills + 8 个 MCP,开发效率直接拉满!
java·后端·claude
Master_oid29 分钟前
机器学习35:元学习的应用
人工智能·学习·机器学习
野犬寒鸦35 分钟前
JVM垃圾回收机制面试常问问题及详解
java·服务器·开发语言·jvm·后端·算法·面试
想七想八不如1140843 分钟前
SQL操作学习
数据库·sql·学习
_杨瀚博1 小时前
JAVA找出哪个类import了不存在的类
java·后端
雷工笔记1 小时前
AI使用|通过AI学习物料分类编码表
笔记·学习
OKkankan1 小时前
深入理解linux进程
java·linux·c++
Shea的笔记本1 小时前
MindSpore实战笔记:WaveNet音乐生成复现全记录
笔记
java1234_小锋1 小时前
Java高频面试题:Spring-AOP通知和执行顺序?
java·开发语言·spring