单例模式五种写法

news2024/11/8 4:18:33

饿汉式(线程安全)

public class Singleton {
    // 直接创建实例,在类加载时就完成实例化
    private static final Singleton instance = new Singleton();

    // 私有构造函数
    private Singleton() {}

    // 提供公共的静态方法获取实例
    public static Singleton getInstance() {
        return instance;
    }
}

优点:

  • 简单
  • 实例在类加载时创建好,类加载器在JVM中保证了线程安全

缺点:

  • 没用到就会浪费,占资源 

懒汉式(线程不安全)

public class Singleton {
    // 先不创建实例,初始化为null
    private static Singleton instance;

    // 私有构造函数
    private Singleton() {}

    // 一个外部方法去获取,只有第一次获取时创建
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

优点:

  • 只在需要时创建实例,避免了资源浪费

缺点:

  • 在多线程情况下可能有多个getInstance()同时被调用,创建多个实例,这就违背了单例模式,所以是多线程不安全的

 懒汉式(单锁)

public class Singleton {
    // 先不创建实例,初始化为null
    private static Singleton instance;

    // 私有构造函数
    private Singleton() {}

    // 一个外部方法去获取,只有第一次获取时创建
    // 加synchronized 上锁保证线程安全
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

优点:

  • 只在需要时创建实例,避免了资源浪费
  • 确保了线程安全

缺点:

  • 使用了互斥锁,会带来一定的性能开销

懒汉式(双检锁) 

public class Singleton {
    // 先不创建实例,初始化为null
    // 加volatile关键字实现多线程的可见性
    private static volatile Singleton instance;

    // 私有构造函数
    private Singleton() {}

    public static Singleton getSingleton() {  
    if (singleton == null) {  
        // 锁定类,后续一小段时间的线程会在这里等待
        synchronized (Singleton.class) {  
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
        }  
    }  
    return singleton;  
    }

}

优点:

  • 只在需要时创建实例,避免了资源浪费
  • 通过双重检查锁定机制,既保证了在多线程环境下实例的唯一性,又减少了不必要的同步开销。在实例已经创建完成的情况下,后续调用getInstance()方法时,不需要再进行同步检查,提高了性能。

缺点:

  • 相较于前几种有一丢丢复杂

静态内部类

public class Singleton {  
    private static class SingletonHolder {  
    // 通过静态内部类在调用类时通过类加载创建实例
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2235532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

远程控制项目第四天 功能实现

发送屏幕内容 代码详解 1. 创建 CImage 对象并获取屏幕内容 首先,我们创建一个 CImage 对象,用于接收屏幕上的内容。要获取屏幕内容,我们需要先获取当前设备上下文(DC)。调用 ::GetDC(NULL) 函数,参数 NU…

无线领夹麦克风哪个品牌音质最好?无线麦克风品牌排行榜前十名

​无线领夹麦克风哪个品牌音质最好?选择无线麦克风时,音质和耐用性至关重要。近年来,无线麦克风产品越来越智能化和多样化,但也存在着大量的劣质产品。作为测评师,我发现这些低质量无线麦克风由于缺乏专业调校&#xf…

【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】

在 Kubernetes 中,NodePort 类型的 Service 允许用户通过每个节点的 IP 地址和指定的端口访问应用程序。如果 NodePort 类型的 Service 无法通过节点的 IP 地址和指定端口进行访问,可能会导致用户无法访问应用。本文将详细分析该问题的常见原因及其解决方…

并发编程(8)—— std::async、std::future 源码解析

文章目录 八、day81. std::async2. std::future2.1 wait()2.2 get() 八、day8 之前说过,std::async内部的处理逻辑和std::thread相似,而且std::async和std::future有密不可分的联系。今天,通过对std::async和std::future源码进行解析&#x…

在VSCode中读取Markdown文件

在VSCode安装Markdown All in One或Markdown Preview Enhanced即可 插件Markdown All in One GitHub:https://github.com/yzhang-gh/vscode-markdown v3.6.2下载链接:https://marketplace.visualstudio.com/_apis/public/gallery/publishers/yzhang/vs…

成都睿明智科技有限公司共赴抖音电商蓝海

在这个短视频风起云涌的时代,抖音作为现象级的社交媒体平台,不仅改变了人们的娱乐方式,更悄然间重塑了电商行业的格局。在这片充满机遇与挑战的蓝海中,成都睿明智科技有限公司凭借其敏锐的市场洞察力和专业的服务能力,…

MySQL_聚合函数分组查询

上篇复习: 设计数据库时的三大范式1.第一范式,一行数据中每一列不可再分 关系型数据库必须要满足第一范式,设计表的时候,如果每一列都可以用SQL规定的数据类型描述,就天然满足第一范式. 2.第二范式,在第一…

深入了解逻辑回归:机器学习中的经典算法

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

TESSY学习笔记—project view界面的架构

1:project view界面能添加的元素 project view界面能添加的元素(暂且称为元素),打开project view界面,下图中红框勾选出来的就是 2:一共存在5种可添加元素 **1)Test collection 测试集合&…

distrobox install in ubuntu 22.04 / 在 ubuntu 22.04 上安装 distrobox (***) OK

要点: 本测试实验,采用的是 podman distrobox 在沙盒 snap 中,安装 distrobox 需要使用 --devmode 开发模式;可以避开 distrobox 的版本检查? distrobox 官方文档显示, Installation https://distrobox.i…

跨域及解决跨域

什么是跨域 前端与后端不在同一个域名下: 解决 import jakarta.servlet.*; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component;import java.io.IOException…

使用Jest进行JavaScript单元测试

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Jest进行JavaScript单元测试 引言 Jest 简介 安装 Jest 创建基本配置 编写测试用例 运行测试 快照测试 模拟函数 代码覆盖率…

【读书笔记/深入理解K8S】集群网络

前言 上一章讲了集群控制器的一个大概的原理,这一章讲一下集群网络。网络是集群通信的载体,因为该书是阿里云团队出品的,所以也以阿里云的集群网络方案为例,其他云厂商的网络集群方案一般来说也大同小异。所以通过本章的学习&…

Varjo核电厂虚拟仿真培训解决方案

虚拟现实技术的融入将帮助核电厂设计验证和操作员培训跟有效的进行。 芬兰的Loviisa工厂是世界上第一个为控制室操作员建造专用VR培训室的核电站。该工厂使用了Varjo混合现实头显设备为员工提供虚拟仿真训练。 案例Fortum: VR为核电厂操纵员培训带来明显优势 与构建物理模拟器相…

推荐一款基于Flash的交互式园林设计工具:Garden Planner

Garden Planner是一款由Artifact Interactive开发的基于Flash的交互式园林设计工具。它允许用户以拖放的方式安排植物、树木、建筑物和各种对象,使园林规划变得简单直观。此外,Garden Planner提供工具来快速创建铺路、路径和围栏,帮助用户设计…

HTML 标签属性——id、class、style 等全局属性详解

文章目录 1. id属性2. class属性3. style属性4. title属性5. lang属性6. dir属性7. accesskey属性8. tabindex属性小结HTML全局属性是一组可以应用于几乎所有HTML元素的特殊属性。这些属性提供了额外的功能和信息,使得网页开发者能够更好地控制元素的行为、样式和可访问性。 …

SpringBoot 整合达梦数据库 Demo

本文将介绍如何在 Spring Boot 项目中整合达梦数据库,并实现基本的用户管理功能。通过以下步骤,我们将创建一个简单的 RESTful API,以便于用户的增删改查(CRUD)操作。 【点我: 下载整套源码】 1. 创建数据库与数据表 …

高校实验室安全巡检系统设计与实现(源码+定制+开发)高校实验室巡检系统、实验室安全管理平台、实验室安全监控系统、智能实验室巡查系统、高校实验室风险管理

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

【系统集成项目管理工程师教程】第4章 信息系统架构

教程内容总结,供参考,有错误请指正,友好交流。 4.架构基础 4.1.1指导思想 4.1.2设计原则 原则内容:包括坚持以人为本、创新引领、问题导向、整体协同、安全可控、科学实施等,这些原则应基于组织的信念和价值观&…

如何学习C++游戏开发

学习C游戏开发是一个涉及多个领域的复杂过程,包括编程、游戏设计、图形学等。 1. **学习C基础**: - 掌握C的基本语法和面向对象编程。 - 学习C标准库,特别是STL(标准模板库)。 2. **理解游戏开发概念**&#xf…