设计模式详解---单例模式

1. 设计模式详解

        单例模式是一种创建对象的设计模式,它确保一个类只有一个实例,并提供全局访问点以获取该实例。

        在单例模式中,类负责创建自己的唯一实例,并确保任何其他对象只能访问该实例。这对于需要共享状态或资源的情况非常有用,例如数据库连接,日志记录器或线程池。

单例模式的主要特点包括:

  1. 私有构造函数:单例类的构造函数被声明为私有,这样其他类无法直接实例化该类。

  2. 静态实例变量:单例类内部维护一个静态实例变量,用于保持对单例实例的引用。

  3. 静态获取方法:单例类提供一个静态方法,以便其他类可以通过该方法获取单例实例。通常,该方法在首次调用时会创建单例实例,并在后续调用时返回该实例。

2.单例模式代码

单例模式实现代码很简单:

/**
 * @Author: stukk
 * @Description: 单例模式
 * @DateTime: 2023-12-17 22:14
 **/
public class Singleton {
    private static Singleton singleton;
    private Singleton(){}

    public static Singleton getInstance() {
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
    public void showMessage(){
        System.out.println("我是单例模式");
    }
}

/**
 * @Author: stukk
 * @Description: 客户端
 * @DateTime: 2023-12-17 22:16
 **/
public class SingletonMode {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        singleton.showMessage();
    }
}

 

3. 单例模式的多种实现方式

单例模式有多种形式,每种形式都在实现单例模式的基本原则上略有不同。

3.1. 懒汉式单例模式(Lazy Initialization):

也就是上面展示的代码

特点:在首次调用获取实例的方法时才创建单例实例

优点:延迟实例化,节省资源

缺点:需要考虑线程安全

线程安全版本:

public class LazySingleton {
    private static LazySingleton singleton;
    private LazySingleton(){}

    public static synchronized LazySingleton getInstance() {
        if(singleton == null){
            singleton = new LazySingleton();
        }
        return singleton;
}
3.2. 饿汉式单例模式(Eager Initialization):

特点:在类加载的时候就创建单例实例

优点:简单直接、线程安全

缺点:加载的时候就实例化,可能会实例到不需要使用的类,浪费资源

代码:

/**
 * @Author: stukk
 * @Description: 饿汉式单例模式
 * @DateTime: 2023-12-17 22:31
 **/
public class EagerSingleton {
    private EagerSingleton(){}
    private static EagerSingleton singleton = new EagerSingleton();
    public static EagerSingleton getInstance(){
        return singleton;
    }

    public void showMessage(){
        System.out.println("我是饿汉单例模式");
    }
}

3.3.双重检查锁单例模式(DCL——Double-Checked-Locking)

特点:结合了懒汉式与同步锁机制,在首次调用获取实例的方法式进行双重检查,提高性能。

优点:延迟实例化且线程安全,性能相对较高

缺点:在某些情况下可能还是会出错,比如多线程环境下的指令重排序,会导致不正确的结果。

示例代码:

/**
 * @Author: stukk
 * @Description: 双重检查锁单例模式
 * @DateTime: 2023-12-17 22:41
 **/
public class DCLSingleton {
    private DCLSingleton(){}
    private volatile static DCLSingleton dclSingleton;

    public static DCLSingleton getInstance(){
        if(dclSingleton == null){
            synchronized (DCLSingleton.class){
                if(dclSingleton == null){
                    dclSingleton = new DCLSingleton();
                }
            }
        }
        return dclSingleton;
    }
    public void showMessage(){
        System.out.println("我是双重校验锁单例模式");
    }
}

3.4. 枚举单例模式(Enum)

特点:使用枚举类实现单例,枚举类保证只有一个实例。

优点:简单、线程安全、防止反射和序列化攻击。

示例代码:(这里以计数器为例子)

/**
 * @Author: stukk
 * @Description: 使用枚举实现
 * @DateTime: 2023-12-17 22:46
 **/
public enum EnumSingleton {
    INSTANCE;
//    假设是个计数器
    private int counter;

//    私有构造函数
    private EnumSingleton(){
        counter = 0;
    }

//    获取计数器的值
    public int getCounter(){
        return counter;
    }

//    计数器++
    public void addCounter(){
        counter ++;
    }

//    其他 操作
    public void showMessage(){
        System.out.println("我是枚举单例模式,此时计数器值为:"+getCounter());
    }
}

/**
 * @Author: stukk
 * @Description: 客户端
 * @DateTime: 2023-12-17 22:16
 **/
public class SingletonMode {
    public static void main(String[] args) {
        EnumSingleton singleton = EnumSingleton.INSTANCE;
        singleton.showMessage();
        singleton.addCounter();
        singleton.showMessage();

    }
}

枚举单例模式的使用非常简单,只需要使用枚举类的名称后跟 .INSTANCE 即可获取到单例实例,无需担心线程安全性或其他实现细节。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[楚慧杯 2023] web

文章目录 eaaevalupload_shell eaaeval 打开题目&#xff0c;源码给了用户密码 登陆后啥也没有&#xff0c;扫一下发现源码泄露www.zip <?php class Flag{public $a;public $b;public function __construct(){$this->a admin;$this->b admin;}public function _…

医疗智能化革命:AI技术引领医疗领域的创新进程

一、“AI”医疗的崛起 随着人工智能&#xff08;AI&#xff09;技术的崛起&#xff0c;"AI"医疗正在以惊人的速度改变着医疗行业的面貌。AI作为一种强大的工具&#xff0c;正在为医疗领域带来前所未有的创新和突破。它不仅在医学影像诊断、病理学分析和基因组学研究等…

京东体育用品销售数据分析与可视化系统

京东体育用品销售数据分析与可视化系统 前言数据爬取模块1. 数据爬取2. 数据处理3. 数据存储 数据可视化模块1. 数据查看2. 店铺商品数量排行3. 整体好评率4. 不同品牌市场占比5. 品牌差评率排名6. 品牌价格排名7. 品牌评论数量分布 创新点 前言 在体育用品行业&#xff0c;了…

ElasticSearch学习篇8_Lucene之数据存储(Stored Field、DocValue、BKD Tree)

前言 Lucene全文检索主要分为索引、搜索两个过程&#xff0c;对于索引过程就是将文档磁盘存储然后按照指定格式构建索引文件&#xff0c;其中涉及数据存储一些压缩、数据结构设计还是很巧妙的&#xff0c;下面主要记录学习过程中的StoredField、DocValue以及磁盘BKD Tree的一些…

实现el-table操作列点击弹出echarts

代码&#xff1a; <el-table-column :width"90"><template #default"scope"><el-popover placement"left-end" width"550" trigger"click"><div><div style"font-size: 18px; margin-left…

Harmony4.0鸿蒙应用开发初识+实践小案例

Harmony4.0鸿蒙应用开发初识实践小案例 一、华为的“18N”产品战略 在华为HarmonyOS及全场景新品发布会上&#xff0c;华为介绍了华为“18N”三圈层全场景智慧生态解决方案&#xff0c;从而打造面向未来的全新生态&#xff0c;其中&#xff0c;1指的是手机&#xff0c;8指的是…

Python Django 连接 PostgreSQL 操作实例

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python Django 连接 PostgreSQL 操作实例&#xff0c;全文3500字&#xff0c;阅读大约10分钟 在Web开发中&#xff0c;使用Django连接到PostgreSQL数据库是一种常见的选择。…

云计算:Vmware 安装 FreeNAS

目录 一、实验 1.Vmware 安装 FreeNAS 2.配置Web界面 二、问题 1.iSCSI如何限定名称 2.LUN和LVM的区别 一、实验 1.Vmware 安装 FreeNAS &#xff08;1&#xff09;环境准备 VMware Workstation 17 FreeNAS相关安装部署镜像: 官网地址&#xff1a; https://download…

磁力计LIS2MDL开发(3)----九轴姿态解算

磁力计LIS2MDL开发.3--九轴姿态解算 概述视频教学样品申请完整代码下载使用硬件欧拉角万向节死锁四元数法姿态解算双环PI控制器偏航角陀螺仪解析代码 概述 LIS2MDL 包含三轴磁力计。 lsm6ds3trc包含三轴陀螺仪与三轴加速度计。 姿态有多种数学表示方式&#xff0c;常见的是四元…

手机上的python怎么运行,python在手机上怎么运行

大家好&#xff0c;本文将围绕python程序如何在手机端运行展开说明&#xff0c;python程序如何在手机上运行是一个很多人都想弄明白的事情&#xff0c;想搞清楚手机上的python怎么运行需要先了解以下几个事情。 如何用手机编程Python&#xff1f; 1.QPython3&#xff1a;这是一…

Vue 自定义搜索输入框SearchInput

效果如下&#xff1a; 组件代码 <template><div class"search-input flex flex-space-between flex-center-cz"><input type"text" v-model"value" :ref"inpuName" :placeholder"placeholder" keyup.enter&…

MySQL日志管理,备份与恢复

备份的主要目的是灾难恢复&#xff0c;备份还可以测试应用、回滚数据修改、查询历史数据、审计等。 而备份、恢复中&#xff0c;日志起到了很重要的作用 MySQL日志管理是数据库管理中的一个重要方面&#xff0c;它可以用于诊断问题、监控性能、进行故障恢复等。MySQL主要有几种…

VSCode 常用的快捷键和技巧系列(2)

一、如何让VSCode工程树显示图标 第一步&#xff1a;安装 快捷键 CtrlP &#xff0c;输入 ext install vscode-icons &#xff0c;然后点击安装插件 第二步&#xff1a;配置 安装成功后&#xff0c;点击Reload重新加载。 然后配置&#xff0c;当前图标使用VsCode-Icons Go…

1264. 动态求连续区间和(树状数组---某个位置加上一个数/求在线(动态)前缀和/蓝桥杯)

题目&#xff1a; 输入样例&#xff1a; 10 5 1 2 3 4 5 6 7 8 9 10 1 1 5 0 1 3 0 4 8 1 7 5 0 4 8输出样例&#xff1a; 11 30 35 树状数组&#xff1a; 代码&#xff1a; #include<cstdio> #include<iostream> using namespace std;const int N100010; int n,…

【Python从入门到进阶】44、Scrapy的基本介绍和安装

接上篇《43.验证码识别工具结合requests的使用》 上一篇我们学习了如何使用验证码识别工具进行登录验证的自动识别。本篇我们开启一个新的章节&#xff0c;来学习一下快速、高层次的屏幕抓取和web抓取框架Scrapy。 一、Scrapy框架的背景和特点 Scrapy框架是一个为了爬取网站数…

Qt/C++音视频开发60-坐标拾取/按下鼠标获取矩形区域/转换到视频源真实坐标

一、前言 通过在通道画面上拾取鼠标按下的坐标&#xff0c;然后鼠标移动&#xff0c;直到松开&#xff0c;根据松开的坐标和按下的坐标&#xff0c;绘制一个矩形区域&#xff0c;作为热点或者需要电子放大的区域&#xff0c;拿到这个坐标区域&#xff0c;用途非常多&#xff0…

linux应急响应基础和常用命令

linux应急响应 linux应急响应基础和常用命令基于linux系统本身进行应急响应。 系统基础信息获取 获取linux服务器基本信息 命令&#xff1a; uname -a内存cpu信息 cat /proc/cpuinfo cat /proc/meminfo lscpu free -m lsmod #查看载入的模块信息进程查看 动态进程查看 …

将mjpg格式数转化成opencv Mat格式

该博客可以解决如下两个问题&#xff1a; 1、将mjpg格式数据转化成opencv Mat格式 2、v4l2_buffer 格式获取的mjpg格式数据转换成Mat格式。 要将 MJPEG 格式的数据转换为 OpenCV 的 Mat 格式&#xff0c;您可以使用 imdecode 函数。imdecode 函数可以将图像数据解码为 Mat 对象…

CCNP课程实验-OSPF-CFG

目录 实验条件网络拓朴需求 配置实现基础配置1. 配置所有设备的IP地址 实现目标1. 要求按照下列标准配置一个OSPF网络。 路由协议采用OSPF&#xff0c;进程ID为89 &#xff0c;RID为loopback0地址。3. R4/R5/R6相连的三个站点链路OSPF网络类型配置成广播型&#xff0c;其中R5路…

电子电器架构( E/E) 演化 —— 高速 大算力

电子电器架构( E/E) 演化 —— 高速 & 大算力 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要…
最新文章