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

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

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

相关推荐
im_AMBER4 分钟前
React 09
前端·javascript·笔记·学习·react.js·前端框架
oak隔壁找我5 分钟前
ShardingJdbc配置说明
java·后端
lzjava202439 分钟前
Spring AI实现一个智能客服
java·人工智能·spring
BreezeJuvenile42 分钟前
外设模块学习(10)——红外避障模块(STM32)
stm32·单片机·学习·红外避障模块
Mos_x1 小时前
HeidiSQL导入与导出数据
java·后端
codeyanwu1 小时前
SQL 学习笔记
笔记·sql·学习
oak隔壁找我1 小时前
Elasticsearch QueryBuilders 高级使用案例
java·后端
青云交1 小时前
Java 大视界 -- Java 大数据在智能家居能源消耗模式分析与节能策略制定中的应用
java·大数据·智能家居·数据采集·能源消耗模式分析·节能策略制定·节能效果评估
Zhang青山1 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
71-31 小时前
C语言——函数声明、定义、调用
c语言·笔记·学习·其他