设计模式随笔-单例模式

单例模式

使用场景

多线程项目中,某资源项需单一存储或者单一处理则使用单例模式,保证资源项唯一性

实现关键

需将类构造方法设为私有构造,避免外部对象初始化,方可保证单例

单例分类

1.饥汉式加载

在项目加载时直接创建并初始化单例对象

优点

  • 程序加载时已经完成创建并初始化,不用考虑加锁问题,代码简单

缺点

  • 初始直接加载,可能加载后长时间不使用,浪费资源
class HungerSingle{
    private static ArrayList<String> instance = new ArrayList<>();
    // 私有实例化方法避免对象多此创建保证单例
    private HungerSingle() {
    }
    // 获取实例
    public static ArrayList<String> getInstance(){
        return instance;
    }
}

2.懒汉式加载

相对饿汉式单例加载而言,项目加载时并不创建单例实例,在第一次读取单例对象时才进行创建并初始化

优点

  • 只在第一次调用的时候创建单例实例,避免资源浪费

缺点

  • 为避免多线程竞争问题,需要加锁,代码较饿汉式加载略微复杂

普通写法-获取实例方法未枷锁,可能多次初始化,线程不安全

class LazySingle {
    private static ArrayList<String> instance;
    // 私有实例化方法避免对象多此创建保证单例
    private LazySingle() {
    }
    // 获取实例
    public static ArrayList<String> getInstance() {
        if (instance == null) {
            instance = new ArrayList<>();
        }

        return instance;
    }
}

单锁写法-此次获取实例方法加锁,性能较低

class LazySingle{
    private static  ArrayList<String> instance;
    // 私有实例化方法避免对象多此创建保证单例
    private LazySingle() {
    }
    // 获取实例-静态方法加锁(类锁),保证多对象线程安全
    public synchronized static  ArrayList<String> getInstance(){
        if(instance==null){
            instance =new ArrayList<>();
        }
        return instance;
    }
}

双检锁写法-兼顾性能和线程安全

class LazySingle{
    private static  ArrayList<String> instance;
    // 私有实例化方法避免对象多此创建保证单例
    private LazySingle() {
    }
    // 获取实例
    public static ArrayList<String> getInstance(){
        // 当instance不为null时直接返回,避免锁等待,提升性能
        if(instance==null){
            // 对instance初始化进行加锁(持有类锁),保证线程安全
            synchronized (LazySingle.class){
                if(instance==null){
                    instance =new ArrayList<>();
                }
            }
        }

        return instance;
    }
}
posted @   宋洛良遥  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示