当前位置: 首页 > article >正文

手写单例模式

饿汉式加载模式(线程安全)

类一加载就创建对象,这种方式比较常用

优点:线程安全,没有加锁,执行效率高

缺点:不是懒加载,类初始化的时候就加载,浪费内存空间

package com.example.threadpool.Singleton;

public class Singleton1 {
    //私有化构造方法
    private Singleton1(){}

    //定义一个静态变量指向自己类型
    private final static Singleton1 instance=new Singleton1();

    //对外提供一个公共的方法获取实例
    public static Singleton1 getInstance() {
        return instance;
    }
}

懒汉式加载模式(线程不安全)

线程下使用没有问题,但是多线程无法保证单例

优点:懒加载

缺点:线程不安全

我们的Singleton instance对象是静态变量,我们多线程没有上锁的情况下,可能错误判断instance为null,然后生成多个instance

package com.example.threadpool.Singleton;

/**
 * 懒汉式加载模式
 */
public class Singleton2 {

    //私有化构造方法
    private Singleton2(){}

    //定义一个静态变量指向自己的类型
    private static Singleton2 instance;

    //对外提供一个公共方法来获取实例
    public static Singleton2 getInstance(){
        if(instance==null){
            instance =new Singleton2();
        }
        return instance;
    }

}


懒汉式加载模式(线程安全)

synchronized关键字在初始化方法上,可以保证线程安全

优点:懒加载,线程安全

缺点:效率低,每一个调用getInstace获取实例的时候我们都需要加锁和释放锁

加锁了,就会保证多线程下创建的仍然是一个对象

package com.example.threadpool.Singleton;

public class Singleton3 {
    //私有化构造方法
    private Singleton3(){}
    //定义一个静态变量指向自己的类型
    private static Singleton3 instance;

    //对外提供一个公共的方法获取实例
    public synchronized static Singleton3 getInstance(){
        if(instance==null){
            instance=new Singleton3();
        }
        return instance;
    }


}

双重判定锁(线程安全)

我们多线程下会有个二次判断,这样子我们多线程下同时判断为null,但是我们锁住一个线程后有了这个初始化实例,我们第一个判断为null的线程再做一次判断,就可以拿到正确的初始化对象

双重判定锁的优先:

避免不必要的同步开销
在单例模式中,传统实现会将整个 getInstance() 方法同步(即 synchronized),这样即使单例对象已经创建,仍然会有大量线程竞争锁,导致性能下降。
双重判定锁通过在进入同步块之前添加一次非同步的检查,可以避免每次调用都进行同步(也就是用了一次是否为null的初步判断,减少了我们调用同步方法的线程),只有在实例为 null 的情况下才进入同步

package com.example.threadpool.Singleton;

/**
 * 双重判定锁
 */
public class Singleton4 {
    //私有化一个构造方法
    private Singleton4(){}

    //定义一个静态变量指向自己
    private static Singleton4 instance;

    //对外提供一个公共方法来获取实例
    public static  Singleton4 getInstance(){
        if(instance==null){
            synchronized (Singleton4.class){
                if(instance==null) {
                    instance = new Singleton4();
                }
            }
        }
        return instance;
    }

}

http://www.kler.cn/a/531805.html

相关文章:

  • 【memgpt】letta 课程1/2:从头实现一个自我编辑、记忆和多步骤推理的代理
  • MATLAB实现单层竞争神经网络数据分类
  • 新到手路由器宽带上网设置八步法
  • 【小白学AI系列】NLP 核心知识点(六)Softmax函数介绍
  • UE编辑器工具
  • 负载均衡器高可用部署
  • Java循环操作哪个快
  • bootstrap.yml文件未自动加载问题解决方案
  • 【回溯+剪枝】优美的排列 N皇后(含剪枝优化)
  • 【游戏设计原理】98 - 时间膨胀
  • SpringBoot 引⼊MybatisGenerator
  • 【C++ STL】vector容器详解:从入门到精通
  • IBM Cognos Analytics配置LTPA SSO单点登录
  • 【02】智能合约与虚拟机
  • Node 服务器数据响应类型处理
  • SLAM技术栈 ——《视觉SLAM十四讲》学习笔记(一)
  • c++ stl 遍历算法和查找算法
  • BMS和无刷电机产品拆解学习
  • TryHackMe: TryPwnMe Two
  • 使用递归解决编程题
  • 编程AI深度实战:AI编程工具哪个好? Copilot vs Cursor vs Cody vs Supermaven vs Aider
  • redis教程
  • 《苍穹外卖》项目学习记录-Day11销量排名统计
  • JavaScript系列(55)--安全编程实践详解
  • 代码随想录二刷|二叉树7
  • Leetcode 3440. Reschedule Meetings for Maximum Free Time II