首页 > 资讯 >

Java设计模式【单例模式】

2023-05-12 17:32:11 来源:博客园
Java设计模式【单例模式】单例模式

单例模式(Singleton Pattern)是一种创建型设计模式,其主要目的是确保一个类只有一个实例,并提供对该实例的唯一访问点。


(资料图)

优缺点

优点:

提供了对唯一实例的受控访问。

由于在系统内存中只存在一个对象,因此可以节约系统资源。

缺点

单例类的扩展有很大的困难。

单例类的职责过重,在一定程度上违背了“单一职责原则”。

对象生命周期。 单例模式没有提出对象的销毁,在提供内存的管理的开发语言中,只有单例模式对象自己才能将对象实例销毁,因为只有它拥有对实例的引用。 在各种开发语言中,比如C++,其他类可以销毁对象实例,但是这么做将导致单例类内部的指针指向不明。

单例模式的使用饿汉模式静态成员变量
/** * @author Physicx * @date 2023/5/12 下午10:13 * @desc 单例 * Created with IntelliJ IDEA */public class Singleton {    //初始化实例对象    private static final Singleton instance = new Singleton();    //私有化构造方法    private Singleton() {    }    //提供获取实例对象方法    public static Singleton getInstance() {        return instance;    }}
静态代码块
/** * @author Physicx * @date 2023/5/12 下午10:13 * @desc 单例 * Created with IntelliJ IDEA */public class Singleton {    //实例对象    private static final Singleton instance;    static {        instance = new Singleton();    }    //私有化构造方法    private Singleton() {    }    //提供获取实例对象方法    public static Singleton getInstance() {        return instance;    }}

饿汉式单例的写法适用于单例对象较少的情况,这样写可以保证绝对的线程安全,执行效率比较高。但是缺点也很明显,饿汉式会在类加载的时候就将所有单例对象实例化,这样系统中如果有大量的饿汉式单例对象的存在,系统初始化的时候会造成大量的内存浪费,换句话说就是不管对象用不用,对象都已存在,占用内存。

懒汉模式
public class Singleton {    //实例对象    private static Singleton instance;    //私有化构造方法    private Singleton() {    }    //提供获取实例对象方法(线程安全)    public static synchronized Singleton getInstance() {        if (instance == null) {            instance = new Singleton();        }        return instance;    }}

线程安全的一种懒汉式写法,在类第一次使用的时候初始化,获取实例的静态方法由synchronized修饰,所以是线程安全的。这种方法每次获取实例对象都加锁同步,效率较低。

双重检测机制(DCL)
public class Singleton {    //实例对象    private static volatile Singleton instance;    //私有化构造方法    private Singleton() {    }    //提供获取实例对象方法    public static Singleton getInstance() {        if (instance == null) {            //加锁处理            synchronized (Singleton.class) {                if (instance==null) {                    //初始化                    instance = new Singleton();                }            }        }        return instance;    }}

实例对象必须用 volatile修饰,否则极端情况可能出现安全隐患。

以上初始化对象代码被编译后会变成以下三条指令:

分配对象的内存空间。

初始化对象。

设置instance指向刚才分配的内存空间。

如果按照上面的执行顺序则不加volatile没有问题,但是CPU或编译器为了提高效率,可能会进行指令重排,最终顺序变为:

分配对象的内存空间。

设置instance指向刚才分配的内存空间。

初始化对象。

当两个线程同时获取实例对象时,线程A已经将instance指向分配空间但未初始化对象,线程B此时第一次判空已不为空,于是返回instance实例,但是此时返回的实例未初始化会导致后续空指针异常。

DCL这种方式同样也是类第一次使用的时候初始化,初始化代码synchronized修饰线程安全,这种方式只会第一次实例对象才会进行同步,因此效率高。

《Java Concurrency in Practice》作者Brian Goetz在书中提到关于DCL的观点:促使DCL模式出现的驱动力(无竞争同步的执行速度很慢,以及JVM启动时很慢)已经不复存在,因而它不是一种高效的优化措施。延迟初始化占位类模式(静态内部类)能带来同样的优势,并且更容易理解。

静态内部类(延迟初始化)
public class Singleton {    //私有化构造方法    private Singleton(){}    //静态内部类(被调用时加载)    private static class SingletonHandle {        private static final Singleton instance = new Singleton();    }    //提供获取实例对象方法    public static Singleton getInstance() {        return SingletonHandle.instance;    }}

利用静态内部类被调用时才加载的特性,通过静态初始化初始Singleton对象,由于JVM将在初始化期间获得一个锁,并且每个线程都至少获取一次这个锁以确保这个类已经加载,因此在静态初始化期间,内存写入操作将自动对所有线程可见。因此无论是在被构造期间还是被引用时,静态初始化的对象都不需要显式的同步。

线程安全,效率高,使用的时候才会初始化不浪费内存。

《Java Concurrency in Practice》作者Brian Goetz 推荐这种单例实现方式。

枚举实现方式

除了以上几种常见的实现方式之外,Google 首席 Java 架构师、《Effective Java》一书作者、Java集合框架的开创者Joshua BlochEffective Java一书中提到:单元素的枚举类型已经成为实现Singleton的最佳方法

在这种实现方式中,既可以避免多线程同步问题;还可以防止通过反射和反序列化来重新创建新的对象。

public class Singleton {    //私有化构造方法    private Singleton() {}    enum SingletonEnum {        SINGLETON;        private final Singleton instance;        SingletonEnum() {            instance = new Singleton();        }        //提供获取实例对象方法        public Singleton getInstance() {            return instance;        }    }}

调用方式如下:

public static void main(String[] args) {        Singleton instance1 = Singleton.SingletonEnum.SINGLETON.getInstance();        Singleton instance2 = Singleton.SingletonEnum.SINGLETON.getInstance();        System.out.println(instance2 == instance1);    }

普通的单例模式是可以通过反射和序列化/反序列化来破解的,jvm虚拟机会保证枚举类型不能被反射并且构造函数只被执行一次,而Enum由于自身的特性问题,是无法破解的。当然,由于这种情况基本不会出现,因此我们在使用单例模式的时候也比较少考虑这个问题。

总结
实现方式优点缺点
饿汉模式线程安全,效率高非懒加载
懒汉模式线程安全,懒加载效率低
双重检测机制线程安全,懒加载,效率高
静态内部类线程安全,懒加载,效率高
枚举线程安全,效率高非懒加载

由于单例模式的枚举实现代码比较简单,而且又可以利用枚举的特性来解决线程安全和单一实例的问题,还可以防止反射和反序列化对单例的破坏,因此在很多书和文章中都强烈推荐将该方法作为单例模式的最佳实现方法

参考:单例模式详解(知乎文章)

设计模式相关其他文章:Java设计模式总结

标签:

Java设计模式【单例模式】

Java设计模式【单例模式】单例模式单例模式(SingletonPattern)是一种创建型设计模式,其主要目的是确保一

2023-05-12

全球热门:硅业分会:短期内需求偏弱 硅价或低位震荡

5月12日,中国有色金属工业协会硅业分会发布消息称,本周工业硅现货市场运行偏弱,硅价整体下行。展望后市

2023-05-12

牛年最旺女孩名字_牛年是哪年-今热点

1、1901年、1913年、1925年、1937年、1949年、1961年、1973年、1985年、1997年、2009

2023-05-12

环球热文:株洲主城区新增监控位置公布 不礼让行人抓拍系统已上线

(通讯员龙百惠张人允)为了维护道路交通秩序,预防和减少交通事故,保护交通参与者的人身和财产安全,提高

2023-05-12

环球视讯!王老吉广告词分析-王老吉广告词

1、王老吉的广告词是:怕上火,喝王老吉!2、吉庆时分,当然是王老吉!普天同庆,当然是王老吉!3、180余年

2023-05-12

鼓楼巧治泵站前池水质 改善居民生活环境 天天热消息

鼓楼巧治泵站前池水质改善居民生活环境“微管家”“安家”鼓楼,湿地“自净”水体近日,在鼓楼区中央北...

2023-05-12

天天最资讯丨美媒:银行股券商股成中国股市新热点

参考消息网5月11日报道据美国《华尔街日报》网站5月9日报道,当美国投资者对银行股感到担忧时,中国的银行

2023-05-11

2022年云南年平均工资公布!这些行业工资最高

5月11日,云南省统计局公布2022年云南省城镇单位就业人员年平均工资情况。

2023-05-11

《看你怎么秀》装修验房通关攻略分享

看你怎么秀这是一款不错的游戏,现在很多网友都在玩,九游小编注意到不少小伙伴都反应对《看你怎么秀》装修

2023-05-11

无服务是卡的问题还是手机的问题_无服务 天天快讯

1、无服务就是没有接入网5261络。2、无服务的情况包括4102:手机1653SIM卡与手机接触不良,导致手机与网络基站

2023-05-11

热门看点:家乐福上海供应链公司被强执176万

家乐福旗下公司被强制执行超百万 天眼查App显示,近日,家乐福(上海)供应链管理有限公司新增3则被执行人

2023-05-11

环球热点!小孩鼻子上长脓包型痘痘怎么办_脓包型痘痘怎么办

1、然后应用过氧化苯甲酰或克林霉素或夫西地酸进行抗炎治疗。2、同时避免抓挠,诱发感染。3、忌辛辣油腻甜

2023-05-11

澳研究发现:皮肤癌可能潜伏在正常皮肤中|当前速读

中新网悉尼5月11日电据澳大利亚第9新闻11日报道,昆士兰大学的一项新研究发现,肉眼并不总是可以看到阳光损

2023-05-11

基于SEA浩瀚架构打造,沃尔沃EX30将于6月7日首发 当前消息

日前,沃尔沃官方宣布称其旗下全新纯电动SUVEX30将于欧洲时间6月7日正式亮相,并在特定国家或地区同步开启

2023-05-11

大学生体能测试怎么查成绩询军人考核表格换算公式

1、大学生体能测试怎么查成绩一:体育本科综合分以750分为满分计算,具体折算方法:本科综合分=考生总分×

2023-05-11

每日聚焦:腾讯课堂教师端使用教程_腾讯课堂教师客户端

1、有啊,PC版的QQ就是客户端如果没有看到就点击上面的加号,如图:然后会出现一个选择界面,把腾讯课堂选上

2023-05-11

快看点丨进贤县发布大雾黄色预警

【来源:进贤县气象台】进贤县气象台2023年05月10日22时38分发布大雾黄色预警信号:预计未来12小时内,白圩

2023-05-11

安徽蚌埠经开区综合执法局开展计量器具监督检查行动-全球讯息

中国质量新闻网讯近日,安徽蚌埠经开区综合执法局聚焦商超、饭店、菜场等民生密切场所,开展严厉打击计量违

2023-05-11

何宇鑫:5.11CPI喜迎“10连降”!黄金多头要反攻了?

每个人都不是你所看到的那个样子,他们都是一边是长着翅膀纯洁善良的天使,一边是拿着夜叉面目狰狞的恶魔。

2023-05-11

杨澜方辟谣移民传闻:我一直是中国人,没改国籍|速看

近日,杨澜方面针对一些不实的移民和改国籍传闻发布了一则声明,明确表示杨澜女士一直是中国公民,没有移民

2023-05-11

为什么这届年轻人基本不走亲戚了?

这届年轻人基本不走亲戚了的原因可能有以下几个方面:1 社交方式的改变:随着社交媒体和移动通信技术的发展

2023-05-11

世界热议:数据挖掘需求巨大 存力一体化成行业热点

【环球网科技综合报道】5月10日消息,近日,在东数西算下数据存力发展研讨会上,华中科技大学武汉光电国家

2023-05-11

货源增多,近期复合肥价格行情快报(5月11日) 即时看

复合肥价格:今日国内复合肥市场局部低端价格货源增多。其中两河及山东地区,玉米肥走货尚可,高端保底、低

2023-05-11

gtx550ti相当于什么显卡_gtx550ti显卡怎么样_环球信息

1、你好楼主说跟GTX650GT740的水准可以无视GTX650跟GT740一样水准但上面者性能是明显比550Ti高一

2023-05-11

河南一季度电子商务增速回升 跨境电商持续增长|每日热议

中新网郑州5月10日电(杨大勇)记者10日从河南省统计局获悉,该省今年一季度商品、服务类电子商务交易额为315

2023-05-11

每日视讯:2023年中国品牌日活动开幕,北京展馆聚焦科技创新等五大板块

【环时深度】两大危机正同时震荡美元霸权!

足坛狙击手无敌!哈兰德或成历史第一得分手,跟C罗穆勒相比如何

【焦点热闻】国际原油期货收跌 美布两油均跌超1%

错过全部红土热身赛纳达尔能出战法网吗 天天微头条

世界观速讯丨广州数据交易所打造全国算力共享新模式 加快推动公共数据赋能实体经济

5月10日基金净值:南方希元转债最新净值1.5127,跌0.64%_全球观察

天天微速讯:特朗普被裁定性侵、赔偿500万美元,如何影响大选?

德赛西威:接受天虫资本管理有限公司等机构调研 焦点讯息

高龄能不能转行做程序员?

鹅卵石到哪里去捡_鹅卵石捡玉石的方法

全球微速讯:崩坏星穹铁道模拟宇宙6必带角色有哪些

洛神赋图赏析_关于洛神赋图内容赏析

基金“乌龙”?大V出手,医疗基金LOF一度直逼涨停

Realme发布真我11Pro+:两亿像素单镜头变焦 售2099元起 前沿资讯

90年我哥结婚时把客厅和主卧之间的墙给拆了,邻居没说什么,不相干的倒是说了闲话|焦点速读

当前观点:真龙主宰(真龙主宰)

李清照:一剪梅_李清照的古诗词 一剪梅 原文是什么|环球快报

申请离婚赔偿流程

世界报道:红星美凯龙家居生活广场开业_红星美凯龙家居生活MALL

2023佛山三水50公里公益徒步报名多少钱?

手游用上PC游戏优化“神技”!天玑9200+加入VRS技术支持

行业风向标 | 政策预期升温,新能源车估值持续修复

磷酸锰商品报价动态(2023-05-10)_世界观热点

文科大学排名2022最新排名_本二文科大学 最新资讯

Copyright @  2015-2022 太平洋家电网版权所有  备案号: 豫ICP备2022016495号-17   联系邮箱:93 96 74 66 9@qq.com