【设计模式】单例模式
单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
- 某个类只能有一个实例。
- 它必须自行创建这个实例。
- 它必须自行向整个系统提供这个实例。
单例模式关键点:
- 构造函数私有化(不让外部创建此类对象)。
- 通过一个静态方法或枚举返回单例类对象。
- 多线程环境下,确保单例(难点)。
- 反序列化不会重新构建对象。
饿汉式
public class Singleton { // 单例对象 private final static Singleton INSTANCE = new Singleton(); // 或 // private final static Singleton INSTANCE; // static { // INSTANCE = new Singleton(); // } // 私有构造方法 private Singleton() { } // 公有静态方法用于获取单例对象 public static Singleton getInstance() { return INSTANCE; } }
线程安全。但是没使用它时,就已经建立了对象,开销内存。
懒汉式
public class Singleton { // 单例对象 private static Singleton INSTANCE = null; // 私有构造方法 private Singleton() { } // synchronized关键字修饰静态方法 public static synchronized Singleton getInstance() { if (null == INSTANCE) {// 空值判断 INSTANCE = new Singleton(); } return INSTANCE; } }
在第一次调用getInstance()
时,创建单例对象。synchronized
关键字修饰,使getInstance()
是一个同步方法。保证多线程情况下单例对象的唯一。但是,同步会耗费资源。
双检锁式(Double Check Lock(DCL))
public class Singleton { // 单例对象,volatile关键字保证INSTANCE的原子性 private volatile static Singleton INSTANCE = null; // 私有构造方法 private Singleton() { } // 两次空值检查,synchronized关键字同步 public static Singleton getInstance() { if (null == INSTANCE) { synchronized (Singleton.class) { if (null == INSTANCE) { INSTANCE = new Singleton(); } } } return INSTANCE; } }
语句INSTANCE = new Singleton();
在编译时的步骤如下:
- 给Singleton的实例分配内存。
- 调用Singleton()的构造函数,初始化成员字段。
- 将INSTANCE 对象指向分配的内存空间(此时对象非空)。
Java编译器允许处理器乱序执行。上诉的2,3两步的顺序可能被打乱。打乱后,非空判断的线程不安全。在JDK1.5之后,调整了JVM,具体化了volatile
关键字,表示此操作是一个原子操作,不能中间被分割执行。使用volatile
关键字会影响性能。
静态内部类
public class Singleton { // 内部类,包含单例的对象 private static class SingletonHolder { public static final Singleton INSTANCE = new Singleton(); } // 私有构造方法 private Singleton() { } // 公有静态方法用于获取单例对象 public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }
第一次加载Singleton
时,SingletonHolder
不会被加载。只用调用getInstance()
时,才加载SingletonHolder
,并创建INSTANCE
。推荐大家使用。
枚举式
public enum SingletonEnum { INSTANCE; }
虽说代码简单,enum
的实质也是class
(编译时,会先翻译成一个class)。优点是反序列化也不会重新生成新的实例。
前几种方式,如果要避免反序列化也不会重新生成新的实例。需要重写:
private Object readResolve() throws ObjectStreamException{ return INSTANCE; }
单例管理类
一个程序可能有多个单例对象。先建立一个上诉管理类。
public class SingletonManager { // 容器 private static Map<String, Object> objMap = new HashMap<String, Object>(); // 私有构造方法 private SingletonManager() { } // 注册单例 public static void ascendSingleton(String key, Object instance) { if (!objMap.containsKey(key)) { objMap.put(key, instance); } } // 获得单例对象 public static Object getInstance(String key) { return objMap.get(key); } }
通过注册,可以管理多种类型的单例,使用统一接口,隐藏具体实现。
使用时:
//注册单例 SingletonManager.ascendSingleton("SingletonKey",Singleton.getInstance());
//获得单例对象 Singleton singleton = SingletonManager.getInstance("SingletonKey");
优点
- 只有一个对象,全局使用。
- 只需要建立一次,占一个内存,节约资源。
缺点
- 没有接口,难以扩展。
- 生命周期长,如果引用短生命周期对象会内存泄漏。
补充
通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。
附件
设计模式Demo
GitHub源码:https://github.com/wzmyyj/Design-Pattern
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Windows 10无法使用debug的解决方案
在学习汇编语言的时候,XP系统或者更早版本的默认在Dos命令下敲入debug即可进入汇编指令模式下,而在Windows 7及更高版本下,这些功能似乎都被阉割了,所以今天我们讲带大家处理一下如何解决这个问题? First 首先我们需要给电脑配置debug文件,以win10为例,默认条件下系统没有debug相关的文件,我们需要自己去配置 下载文件我已经上传了,链接在这里 下载好并解压,结果如下: 此时我们需要记下当前的路径,我们这里当前路径为D:\Debug Second 我们需要下载一个DosBox,根据维基百科上定义讲: DOSBox是一种模拟器软件,主要是在IBM PC兼容机下,模拟旧时的操作系统:MS-DOS,支持许多IBM PC兼容的显卡和声卡,为本地的DOS程序提供执行环境,使这些程序可以正常运行于大多数现代计算机上的不同操作系统。DOSBox特别是为运行早期的计算机游戏所设计,主要以C++编写,是以GNU通用公共许可证许可发布的自由软件。 DOSBox可以运行那些在现代计算机上不能运行的MS-DOS软件,这些软件通常与现在的主流硬件和操作系统有一些不兼容。DOSBox在模拟M...
- 下一篇
人生苦短,我用python!
点击关注异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书 ——异步小编 Python这个无所不在的编程语言,薪资高到没朋友,《Python神经网络编程》的新书发布、Zed大神的《笨办法学Python3》即将出新版后,大家对Python热度持续高涨,有的读者问:“小编什么时候可以带来一波Python书单福利?",今天今天就是今天,小编带来了一份Python书单,分为入门、进阶高级、行业应用三部分内容,带来一大波好书福利给你。 那么今天的问题来了“如果被丢到荒岛上,只能带三本异步图书?你会带哪三本?我的第一反应是:“《笨办法学Python3》、《Python神经网络编程》、《Python机器学习》",如果是你会选择哪本呢? 异步社区Python阅读路线图 (点击放大查看) 编程入门 成人 《“笨办法学”Python3》 Zed Shaw著 (2018年5月) 本书是基于Python 3.6版本编写的。百万粉丝程序员带你轻松入门Python语言! 手机扫码看视频,学习更轻松!5小时的完整视频教程,纯美式发音,搭配中文字幕...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker使用Oracle官方镜像安装(12C,18C,19C)