Java设计模式之创建型-单例模式(UML类图+案例分析)

news2024/11/16 7:47:11

目录

一、基础概念

二、UML类图

三、角色分析

四、案例分析

1、饿汉模式

2、懒汉模式(线程不安全)

3、懒汉模式(线程安全)

4、双重检索模式

5、静态内部类

6、枚举 

五、总结


一、基础概念

单例模式确保一个类只有一个实例,提供一个全局访问点。一般实现方式是把构造函数设为私有,并提供一个静态方法获取实例对象。

二、UML类图

  

三、角色分析

角色描述
Singleton在单例类的内部实现只生成一个实例,同时它提供一个静态的 getInstance()方法,让外部以访问它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有;在单例类内部定义了一个 Singleton类型的静态对象,作为外部共享的唯一实例。

四、案例分析

1、饿汉模式

直接在类内部创建一个静态final常量实例,线程安全,调用效率高,但无法延迟加载。

public class Singleton_Hungry {
    /**
     * 私有实例,静态变量会在类加载的时候初始化,是线程安全的
     */
    private static final Singleton_Hungry instance = new Singleton_Hungry();

    /**
     * 私有构造方法
     */
    private Singleton_Hungry() {
    }

    /**
     * 获取实例的方法
     */
    public static Singleton_Hungry getInstance() {
        return instance;
    }
}

2、懒汉模式(线程不安全)

起初没有实例,第一次调用才初始化,线程不安全,需加锁处理。

public class Singleton_Lazy {
    /**
     * 私有实例
     */
    private static Singleton_Lazy instance;

    /**
     * 私有构造方法
     */
    private Singleton_Lazy() {
    }

    /**
     * 获取实例的方法
     */
    public static Singleton_Lazy getInstance() {
        if (instance == null) {
            instance = new Singleton_Lazy();
        }
        return instance;
    }
}

3、懒汉模式(线程安全)

加锁处理,线程安全但影响效率,大部分情况下不需要同步。

public class Singleton_Lazy_Safe {

    /**
     * 私有实例
     */
    private static Singleton_Lazy_Safe instance;

    /**
     * 私有构造方法
     */
    private Singleton_Lazy_Safe () {
    }

    /**
     * 获取实例的方法,该方法使用synchronized加锁,来保证线程安全性
     */
    public static synchronized Singleton_Lazy_Safe getInstance() {
        if (instance == null) {
            instance = new Singleton_Lazy_Safe ();
        }
        return instance;
    }
}

4、双重检索模式

双重检查锁单例模式是在懒汉式单例模式的基础上,额外加锁保证多线程安全,同时保证效率,并且加入了第二次判断,避免多线程下创建多个实例。

public class Singleton_Lazy_Double {
    
    //用volatile关键字确保 instance 在多线程下的可见性
    private static volatile Singleton_Lazy_Double instance = null;

    //将构造方法私有化,禁止外部通过构造方法创建实例
    private Singleton_Lazy_Double() {}

    //提供一个公共的访问方法,用于获取该类的唯一实例
    public static Singleton_Lazy_Double getInstance() {
        //如果instance为空,就进行实例化
        if (instance == null) {
            //保证多线程下只有一个线程进行实例化
            synchronized (Singleton_Lazy_Double.class) {
                //第二次判断,避免多线程下创建多个实例
                if (instance == null) {
                    instance = new Singleton_Lazy_Double();
                }
            }
        }
        return instance;
    }

}

5、静态内部类

静态内部类单例模式是在类加载时会创建一个静态内部类,调用getInstance方法时才会去加载该内部类并初始化INSTANCE实例。该方式既保证了线程安全,也保证了懒加载和高效访问的特性。

public class SingletonStatic {

    /**
     * 私有构造方法
     */
    private SingletonStatic() {
    }

    /**
     * 取实例的方法
     */
    public static SingletonStatic getInstance() {
        return LazyHolder.INSTANCE;
    }

    /**
     * 私有静态内部类
     */
    private static class LazyHolder {
        private static final SingletonStatic INSTANCE = new SingletonStatic();
    }
}

6、枚举 

使用枚举实现单例模式可以节省大量代码,并且防止多线程安全以及反序列化及反射攻击的问题。

public enum SingletonEnum {

    INSTANCE;

    public void test() {
        System.out.println("hello");
    }

}

五、总结

优点:

在内存中只有一个实例,减少内存开销。避免对资源的多重占用。设置全局访问点,严格控制访问。

缺点:

不符合单一职责原则。扩展困难,如果要扩展需要修改源代码。攻击者可通过反射和反序列化的方式获取实例而破坏单例。

应用场景:

需要频繁实例化然后销毁的对象、创建对象时消耗资源过多的情况等。单例模式应用在工具类、线程池、配置类、对话框、日志对象、缓存等场景中,在工具类中应用是最为典型的。

以上各种实现方式之间存在效率、线程安全、懒加载等方面的权衡和区别,应根据需要选用最合适的单例模式实现。

总体来说,枚举实现单例最大优点是实现简单,天生线程安全,防反射攻击,是首选方式。

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

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

相关文章

工厂能源管控系统

随着现代工业的发展,工厂能源消耗不断增加,能源成本成为企业生产经营的重要组成部分。为了降低能源消耗、提高生产效率和降低成本,越来越多的企业开始采用工厂能源管控系统。本文将从多个方面介绍工厂能源管控系统的全面内容。 一、工厂能源管…

增值税高,怎么办?节省税款的小技巧必知!

增值税高,怎么办?节省税款的小技巧必知! 《税筹顾问》专注于园区招商、企业税务筹划,合理合规助力企业节税! 增值税是所有企业必须要去缴纳的一种税种,它对于企业来说十分熟悉。而企业增值税高的问题也不是…

两部搞定Pytorch 安装与配置(小白也能搞定!!!)

Pytorch 安装与配置 NVIDIA系统管理界面查看 nvidia-smi 进入NVIDIA系统管理界面 对应的详细解释看下图 参考博文 (53条消息) nvidia-smi命令详解和一些高阶技巧介绍_Chaos_Wang_的博客-CSDN博客 CUDA 查看 CUDA 有两类:其中一类是驱动API(Driver API)&#xff…

拥抱“Zero ETL”未来,亚马逊云科技助力乐城堡加速数据分析

获得全球三千五百多万用户的认可的移动游戏企业乐城堡希望通过数据分析为游戏业务提供更好的决策支撑。乐城堡在亚马逊云科技上利用Amazon Redshift等服务构建属于自己的云上游戏数据分析平台,实现复杂查询,保证游戏运营人员能快速、近实时地获取所需的数…

Python-opcua 编程(3)历史数据读写

历史数据就是将opcua 信息模型中的某一些变量保存起来,以便Client 端程序能够读取历史数据,作各种数据处理。 Opcua 标准指出历史数据的读写,主要包括: 属性 Historizing 当设置为True 时,该变量支持历史数据读写 …

kafka主题支持路由功能

背景: 我们知道rabbitmq是支持消息路由的功能的,但是当我们统一消息中间件到kafka后,有一些旧的应用依然想要使用消息路由的功能时,我们可以怎么让kafka也支持消息路由的功能呢? 技术实现: 为了不影响ka…

web实现小米商城首页选择内容

一、需求&#xff1a;实现如下图所示的web内容 二、实现结果 三、代码展示 <!DOCTYPE html> <html> <head><title>小米商场</title><style>body {display: flex;flex-direction: column;align-items: center;justify-content: center;he…

阿里云轻量应用服务器使用教程(以建站为例)

阿里云轻量应用服务器怎么使用&#xff1f;阿里云轻量应用服务器使用教程&#xff1a;轻量应用服务器购买、重置密码、远程连接、宝塔面板的Web环境搭建、WordPress网站程序安装到网站上线&#xff0c;阿里云服务器网分享轻量应用服务器从购买、配置建站环境、轻量服务器应用服…

【SLAM】Ceres优化库超详细解析

Ceres是由Google开发的开源C通用非线性优化库&#xff0c;与g2o并列为目前视觉SLAM中应用最广泛的优化算法库。 对于任何一个优化问题&#xff0c;我们首先需要对问题进行建模&#xff0c;之后采用合适的优化方法&#xff0c;进行求解。在求解的过程中&#xff0c;往往需要进行…

用 Nginx 禁止国外 IP 访问我的网站...

先来说说为啥要写这篇文章&#xff0c;之前看了下 Nginx 的访问日志&#xff0c;发现每天有好多国外的 IP 地址来访问我的网站&#xff0c;并且访问的内容基本上都是恶意的。因此我决定禁止国外 IP 来访问我的网站。 想要实现这个功能有很多方法&#xff0c;下面我就来介绍基于…

(动态规划) 132. 分割回文串 II ——【Leetcode每日一题】

❓ 132. 分割回文串 II 难度&#xff1a;困难 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 1&#xff1a; 输入&#xff1a;s “aab” 输出&#xff1a;1 解释&#xff1a;只需一次分割就…

Vision Transformer (ViT)介绍

paper&#xff1a;An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 摘要 把transformer直接应用于图像块序列&#xff0c;也可以在图像分类任务上表现很好。通过在大数据集上预训练&#xff0c;然后迁移到中等规模和小规模数据集上&#xff0c;…

Android之签字板

文章目录 前言一、效果图二、实现步骤1.GestureSignatureView类2.xml布局3.Activity类(kotlin)4.Activity类(Java)5.动态申请权限(kotlin)6.动态申请权限(Java) 总结 前言 随着公司发展需求&#xff0c;很多金融APP都会涉及到需要用户签字的环节&#xff0c;所以在此贴出代码以…

软考高级架构师笔记-9系统架构

目录 1. 前文回顾 & 考情分析2. 软件架构概述3. 软件架构风格3.1 层次架构风格3.2 面向服务架构风格4. 软件架构复用5. 特定领域软件体系结构DSSA6. ABSD7. 质量属性8. 架构评估9 结语1. 前文回顾 & 考情分析 前文回顾: 软考高级架构师笔记-1计算机硬件软考高级架构师…

TCP 协议(三)十种核心机制

1.确认应答&#xff08;可靠机制&#xff09; 2.超时重传&#xff08;可靠机制&#xff09; 3.连接管理&#xff08;可靠机制&#xff09; 4.滑动窗口&#xff08;效率机制&#xff09; 5.流量控制&#xff08;效率机制&#xff09; 6.拥塞控制&#xff08;效率机制&#xff09…

优维低代码实践:权限设置

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

js两种对象混合写,返回的是哪一个

<script>function jiafa() {this.name "xuhaitao";this.age 36;var obj {};obj.xx "hunkxu";obj.yy "88";return obj;}var aa new jiafa();console.log(aa);</script> 打印&#xff1a; FR&#xff1a;徐海涛(hunk xu)

3D引擎龙头Unity:元宇宙和AI活跃玩家

Unity是用于创建和操作交互式实时3D内容的世界领先平台。凭借灵活的编辑器、友好的开发环境、丰富的工具套件&#xff0c;Unity吸引了大量开发者&#xff0c;全球排名前1000的移动游戏70%以上使用了Unity的创作和运营解决方案&#xff0c;如今&#xff0c;Unity引擎在工业场景、…

leaflet地图移动防抖问题

现在有这么一个需求&#xff0c;当移动地图时&#xff0c;需要获取当前地图范围属于那个城市。如果频繁移动地图&#xff0c;会不停的调用接口获取当前地图视图所属城市&#xff0c;所以加个防抖&#xff0c;减少请求。代码示例&#xff1a;<!DOCTYPE html> <html>…

【Leetcode】36. 有效的数独

一、题目 1、题目描述 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图) 注意:…