手写一个单例模式

手写一个单例模式 (考虑线程安全)。 在软件开发中,有些场景下我们希望某个类永远只创建一个实例。系统的配置管理器:如果有多个配置实例,可能导致配置不一致日志记录器:多个日志实例可能导致日志文件被重复写入数据库连接池:过多连接池实例会浪费资源单例模式(Singleton Pattern)就是为解决这类问题而生的设计模式。确保一个类只有一个实例,并提供一个全局访问点。但在多线程环境下,简单的单例实现可能会"失效"。 阅读详情

一、单例模式的定义

定义: 确保一个类只有一个实例,并提供该实例的全局访问点。

这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗费系统资源。

二、单例模式的设计要素

  • 一个私有构造函数 (确保只能单例类自己创建实例)
  • 一个私有静态变量 (确保只有一个实例)
  • 一个公有静态函数 (给使用者提供调用方法)

简单来说就是,单例类的构造方法不让其他人修改和使用;并且单例类自己只创建一个实例,这个实例,其他人也无法修改和直接使用;然后单例类提供一个调用方法,想用这个实例,只能调用。这样就确保了全局只创建了一次实例。

三、单例模式的6种实现及各实现的优缺点

(一)懒汉式(线程不安全)

实现:

public class Singleton {
     private static Singleton uniqueInstance;

     private Singleton() {

    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

说明: 先不创建实例,当第一次被调用时,再创建实例,所以被称为懒汉式。

优点: 延迟了实例化,如果不需要使用该类,就不会被实例化,节约了系统资源。

缺点: 线程不安全,多线程环境下,如果多个线程同时进入了 if (uniqueInstance == null) ,若此时还未实例化,也就是uniqueInstance == null,那么就会有多个线程执行 uniqueInstance = new Singleton(); ,就会实例化多个实例;

(二)饿汉式(线程安全)

实现:

public class Singleton {

    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        return uniqueInstance;
    }

}

说明: 先不管需不需要使用这个实例,直接先实例化好实例 (饿死鬼一样,所以称为饿汉式),然后当需要使用的时候,直接调方法就可以使用了。

优点: 提前实例化好了一个实例,避免了线程不安全问题的出现。

缺点: 直接实例化好了实例,不再延迟实例化;若系统没有使用这个实例,或者系统运行很久之后才需要使用这个实例,都会操作系统的资源浪费。

(三)懒汉式(线程安全)

实现:

public class Singleton {
    private static Singleton uniqueInstance;

    private static singleton() {
    }

    private static synchronized Singleton getUinqueInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }

}

说明: 实现和 线程不安全的懒汉式 几乎一样,唯一不同的点是,在get方法上 加了一把 锁。如此一来,多个线程访问,每次只有拿到锁的的线程能够进入该方法,避免了多线程不安全问题的出现。

优点: 延迟实例化,节约了资源,并且是线程安全的。

缺点: 虽然解决了线程安全问题,但是性能降低了。因为,即使实例已经实例化了,既后续不会再出现线程安全问题了,但是锁还在,每次还是只能拿到锁的线程进入该方***使线程阻塞,等待时间过长。

(四)双重检查锁实现(线程安全)

实现:

public class Singleton {

    private volatile static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }  
}

说明: 双重检查数相当于是改进了 线程安全的懒汉式。线程安全的懒汉式 的缺点是性能降低了,造成的原因是因为即使实例已经实例化,依然每次都会有锁。而现在,我们将锁的位置变了,并且多加了一个检查。 也就是,先判断实例是否已经存在,若已经存在了,则不会执行判断方法内的有锁方法了。 而如果,还没有实例化的时候,多个线程进去了,也没有事,因为里面的方法有锁,只会让一个线程进入最内层方法并实例化实例。如此一来,最多最多,也就是第一次实例化的时候,会有线程阻塞的情况,后续便不会再有线程阻塞的问题。

为什么使用 volatile 关键字修饰了 uniqueInstance 实例变量 ?

uniqueInstance = new Singleton(); 这段代码执行时分为三步:

  1. 为 uniqueInstance 分配内存空间
  2. 初始化 uniqueInstance
  3. 将 uniqueInstance 指向分配的内存地址

正常的执行顺序当然是 1>2>3 ,但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1>3>2。
单线程环境时,指令重排并没有什么问题;多线程环境时,会导致有些线程可能会获取到还没初始化的实例。
例如:线程A 只执行了 1 和 3 ,此时线程B来调用 getUniqueInstance(),发现 uniqueInstance 不为空,便获取 uniqueInstance 实例,但是其实此时的 uniqueInstance 还没有初始化。

解决办法就是加一个 volatile 关键字修饰 uniqueInstance ,volatile 会禁止 JVM 的指令重排,就可以保证多线程环境下的安全运行。

优点: 延迟实例化,节约了资源;线程安全;并且相对于 线程安全的懒汉式,性能提高了。

缺点: volatile 关键字,对性能也有一些影响。

(五)静态内部类实现(线程安全)

实现:

public class Singleton {

    private Singleton() {
    }

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getUniqueInstance() {
        return SingletonHolder.INSTANCE;
    }

}

说明: 首先,当外部类 Singleton 被加载时,静态内部类 SingletonHolder 并没有被加载进内存。当调用 getUniqueInstance() 方法时,会运行 return SingletonHolder.INSTANCE; ,触发了 SingletonHolder.INSTANCE ,此时静态内部类 SingletonHolder 才会被加载进内存,并且初始化 INSTANCE 实例,而且 JVM 会确保 INSTANCE 只被实例化一次。

优点: 延迟实例化,节约了资源;且线程安全;性能也提高了。

(六)枚举类实现(线程安全)

实现:

public enum Singleton {

    INSTANCE;

    //添加自己需要的操作
    public void doSomeThing() {

    }

}

说明: 默认枚举实例的创建就是线程安全的,且在任何情况下都是单例。

优点: 写法简单,线程安全,天然防止反射和反序列化调用。

  • 防止反序列化
    序列化:把java对象转换为字节序列的过程;
    反序列化: 通过这些字节序列在内存中新建java对象的过程;
    说明: 反序列化 将一个单例实例对象写到磁盘再读回来,从而获得了一个新的实例。
    我们要防止反序列化,避免得到多个实例。
    枚举类天然防止反序列化。
    其他单例模式 可以通过 重写 readResolve() 方法,从而防止反序列化,使实例唯一重写 readResolve() :
private Object readResolve() throws ObjectStreamException{
        return singleton;
}

四、单例模式的应用场景

应用场景举例:

  • 网站计数器。
  • 应用程序的日志应用。
  • Web项目中的配置对象的读取。
  • 数据库连接池。
  • 多线程池。
  • ......

使用场景总结:

  • 频繁实例化然后又销毁的对象,使用单例模式可以提高性能。
  • 经常使用的对象,但实例化时耗费时间或者资源多,如数据库连接池,使用单例模式,可以提高性能,降低资源损坏。
  • 使用线程池之类的控制资源时,使用单例模式,可以方便资源之间的通信。

在armv8架构中,有哪些是serror (3)、RAS(Reliability, Availability, and Serviceability)错误:一些对于系统的可靠性、可用性和可维护性有影响的错误可能会触发 SError。(2)、ECC(Error Correction Code)错误:在访问带有错误校验的内存(如ECC内存)时,如果发现错误校验失败,可能会产生SError。2、其实呢,大多数Serror都是实现定义的,真正实现的serror就没有多少个。Serror(也称System Error),是异步异常的一种,一般是来自。 阅读详情

相关推荐

PowerDesigner16.5下载和安装教程

一、软件下载 1.下载地址(不用复制,直接点击下载链接即可):链接:https://pan.baidu.com/s/1MSnWHWt3SO2Uz5dt9AANAg提取码:z9kk 二、软件安装 1.下载安装包(包含安装文件、汉化包、注册文件) 2.下载后文件内容如下 3....

cicong2374的博客 10万+

单例模式

一、单例模式的定义 定义: 确保一个类只有一个实例,并提供该实例的全局访问点。 这样做的好处是:有些实例,全局只需要一个就够了,使用单例模式就可以避免一个全局使用的类,频繁的创建与销毁,耗费系统资源。 二、单例模式的设计要素 一个私有构造函数 (确保只能单例类自己创建实例) 一个私有静态变量 (确保只有一个实例) 一个公有静态函数 (给使用者提供调用方法) 简单来说就是,单例类的构造方法不让其他人修改和使用;并且单例类自己只创建一个实例,这个实例,其他人也无法修改和直接使用;然后单例类提供一个调用方法,想用

林啾啾的博客 324

Cortex-M内核DWT周期计数器:从原理到STM32实战时间测量与性能分析

在嵌入式开发中,代码执行耗时测量是性能优化的基础。除了依赖外设定时器或SysTick,ARM Cortex-M3/M4/M7内核自带的DWT(Data Watchpoint and Tracker)调试组件提供了一种极低侵入性的硬件计时方案。其内部的32位周期计数器CYCCNT跟随内核时钟递增,无需占用额外引脚或定时器资源,即可实现纳秒级分辨率的函数耗时测量、中断响应分析及延时实现。从DWT寄存器配置、周期差值计算到基于SystemCoreClock的微秒换算,开发者可以快速搭建一套轻量级性能分析工具。本文

weixin_34216614的博客 186

详细了解单例模式

单例模式 单例模式属于设计模式中的创建型。 什么是单例模式 一个类只允许创建一个对象,并提供该实例的全局访问点,这就是单例模式。 应用场景 1. 在资源访问冲突的场景中 在解决资源竞争的场景时,往往是通过加锁的方式来解决竞争。但在有些场景中。可以通过单例模式来解决。例如有个日志类,负责记录系统调用日志,那么这个类就会被频繁访问并将信息写入日志。如果不采用单例模式,那么就会频繁创建对象,耗费系统资源。并且因为不同的对象,锁的粒度也要上升到类级别。对性能的影响也大。 2. 全局唯一类 在业务上,如果某些数据在系

QFann的博客 685

Shopee App加密算法逆向实战:从抓包到libshpssdk.so的深度解析

本文详细解析了Shopee App加密算法的逆向过程,从网络抓包发现加密参数入手,通过Frida动态Hook定位到Java层关键方法,并深入追踪至Native层的libshpssdk.so核心函数。文章结合实战演示了如何利用Unidbg模拟执行环境进行算法分析与验证,并探讨了核心参数生成逻辑及风控规避要点,为移动安全与逆向工程研究提供了完整的技术路径。

weixin_28347369的博客 527

zabbix监控深信服下一代防火墙配置

深信服下一代防火墙v8.0管理界面,zabbix,SNMP

weixin_43996471的博客 6873

java单例变量_java 单例设计模式

单例是应用开发中一种设计模式,主要应用场景为:当且仅当系统中只能保留一个对象时使用。本文提出4中可以在生产环境中使用的单例设计模式。推荐使用enum的方式。应用场景例如一下应用场景[1]:1、 Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗?2、网站的浏览人数统计,一般也是采用单例...

weixin_39566493的博客 291

基于STM32设计的校园智慧路灯系统(华为云IOT)(212)

当前设计并研发了基于STM32的智慧路灯系统,本系统的目的是打造一个高效节能、智能化管理的校园照明环境。通过集成STM32F103RCT6高性能微控制器为核心,结合多种传感器模块如BH1750光敏传感器、热释电人体感应模块以及中科微电子GPS模块等,实现了对校园路灯的精准控制与实时监控。

5137

Java中使用单例模式定义服务全局变量以及使用

在有些情况下一些变量需要在整个项目中都使用到,例如token的验证等都可以将用户信息放入全局配置变量中但是内容不要太大如果太大的话占用系统的资源导致系统变慢,请看下面案例: /** * 一些可以全局配置的变量,内部没有使用spring,只好借助这个类来传递 * spring 初始化的时候给这个对象设置好适当的值 */ public class GlobalSetting { ...

zpflwy1314的博客 2952

CenterPoint 工程复现

CenterPoint 工程复现,本文中使用版本:BEVerse工程下的mmdet3d (`MMDet3d v0.17.3`)版本,MMDetection3D中其他版本的使用`大同小异`。

Darchan的博客 5663

CDD那些事 - DID and SecurityAccess

本文介绍了SecurityAccessSID27的安全访问配置流程:1.通过StateGroups添加Level2群组;2.在Classes定义L2子功能;3.配置4步解锁流程,选择对应解锁等级;4.在DiagnosticInstance设置请求响应。同时说明了DID配置的两种方式:在DIDs页面定义或通过Identification页面创建,前者定义更全面。文章还提到ServiceList支持view/edit模式,其中edit模式可配置DID的多服务支持(如同时支持SID22读取和SID2E写入),但该

ziteng21的博客 256

关于Java的单例设计对象的数值储存

package _06ToObject.Object.DesignStyle; /** * * 设计模式:之前很多程序员经过无数次的尝试,总结出来的一套最佳设计模式 * 单例:一个类在内存当中只有一个对象。别人不能再去创建对象。 * * 单例设计模式 * 一个类只有一个对象实例 * 做一些工具类,买锤子——创建对象 * * 特点 * 1. 单例类只有一个实...

星海君的小窝 536

(建议收藏)2024最新 URL Scheme大全APP跳转界面地址更新中 ios快捷指令快捷方式链接跳转微信小程序必备autojs可用免root (可定制开发和提取URL Scheme 参数提取)

(建议收藏)2024最新 URL Scheme大全APP跳转界面地址更新中 ios快捷指令快捷方式链接跳转微信小程序必备autojs可用免root (可定制开发和提取URL Scheme 参数提取)

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1万+

java手写一个单例模式

目录什么是单例模式?使用单例模式的目的?懒汉式恶汉式懒汉式 双重锁 什么是单例模式? 单例类只能有一个实例 单例类必须自己创建自己的唯一实例 单例类必须给所有其他对象提供这一实例 使用单例模式的目的? 单例模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在 懒汉式 线程不安全单例模式 public class Singleton { private stati...

weixin_44906271的博客 2280

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

用简单易懂的方式手写一个单例模式,看了不会来打我

啊?单例模式实现就这么简单?

jc15274630894的博客 1884

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

优雅的手写一个线程安全的单例模式

单例模式是我们非常常用的设计模式之一。百度百科给出的定义: 单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例) 一般,我们为了实现单例模式,通常把构造器私有化,然后通过静态方法和静态变量来获取一个对象。 懒汉式,线程不安全 这种方式是最基础的实现方式,最大的问题是不支持多线...

qq_36008321的博客 2309

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

java手写单例模式_面试官:请你手写一个单例模式

点击蓝色“Java学习指南”关注我,加个“星标”,每天阅读Java干货文章说实话,看到这个问题,我心里还是有点窃喜的~ 单例模式?不好意思,设计模式我只会单例,哈哈哈,看我一顿操作:publicclassSingleton{privatestaticSingletonsingleton=null;privateSingleton(){}public...

weixin_32762235的博客 308

面试官:请你手写一个单例模式

面试结束~抽空整理下设计模式相关的知识吧?太菜了啊 第一个当然是单例模式啦。面试让你手写一个单例模式你怎么写? 看我一顿操作: public class Singleton { private static Singleton singleton = null; private Singleton() {} public static Singleton getInsta...

程序员青戈 1436

python手写单例模式_面试官:请你手写一个单例模式

说实话,看到这个问题,我心里还是有点窃喜的~ 单例模式?不好意思,设计模式我只会单例,哈哈哈,看我一顿操作:publicclassSingleton{privatestaticSingletonsingleton=null;privateSingleton(){}publicstaticSingletongetInstance(){if(singleton==null)...

weixin_29798379的博客 360

手写一个单例模式,Demo,检测

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。注意:1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

futurn_hero的博客 799

白纸上手写一个单例模式

我的版本是设置一个静态变量,判空为真就实例化一个对象,否则直接返回 如何改进?比如关于锁相关的 转载于:https://www.cnblogs.com/researcher/p/6424328.html

weixin_30897233的博客 93

【设计模式】手写一个线程安全的单例模式

单例模式是我们非常常用的设计模式之一。百度百科给出的定义:单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)一般,我们为了实现单例模式,通常把构造器私有化,然后通过静态方法和静态变量来获取一个对象。

DreamSun的博客 2017

设计模式原理及大数据实践之一:手写一个单例模式

单例模式 错误的例子

砥砺前行的博客 1714

【设计模式】面试官:请你手写一个单例模式!

# 一、什么是单例模式 ## 1.概念 > 单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类**在当前进程中只有一个实例**(根据需要,也有可能**一个线程中属于单例**,如:仅线程上下文内使用同一个实例) > ——百度百科 单例模式就是严格控制一个类的实例,要求在一个进程或一个线程中**只存在一个实例**,如果没有就创建一个实例返回,如果有就返回已经已经存在的实例。不同的单例模式都是为了**确保只有一个实例**。

程序员徐小白的博客 495

手写java设计模式_面试官:请你手写一个单例模式

说实话,看到这个问题,我心里还是有点窃喜的~ 单例模式?不好意思,设计模式我只会单例,哈哈哈,看我一顿操作:publicclassSingleton{privatestaticSingletonsingleton=null;privateSingleton(){}publicstaticSingletongetInstance(){if(singleton==null)...

weixin_28933797的博客 192
上一篇: 数据库锁升级问题
下一篇: Spring AOP基础、快速入门(Spring的设计思想之一)
涵冰...
博客等级 码龄4年 2438粉丝 243原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涵冰...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值