单例模式五种实现方式以及在JDK中的体现
单例模式五种实现方式以及在JDK中的体现
一、五种实现方式
1、饿汉式
- 构造私有
- 提供一个静态私有的成员常量,类型就是单例类型,值是用私有构造创造出来的唯一实例
- 提供公共的静态方法获取上述的静态成员常量
public class Singleton1 implements Serializable {
//(1)构造私有
private Singleton1(){
//添加if判断防止单例模式被破坏
if(INSTANCE != null) {
throw new RuntimeException("单例构造器禁止反射调用");
}
System.out.println("private Singleton1()");
}
//(2)提供一个静态私有的成员常量,类型就是单例类型,值是用私有构造创造出来的唯一实例
private static final Singleton1 INSTANCE = new Singleton1();
//(3)提供公共的静态方法获取上述的静态成员常量
public static Singleton1 getInstance() {
return INSTANCE;
}
}
注意:对应所有的单例模式实现方式,如果实现Serializable接口,可能会被反射,反序列化等操作破坏单例,
2、枚举饿汉式
- 枚举类,只定义一个变量
- 构造私有
- 提供公共的静态方法获取枚举常量
public enum Singleton2 {
//(1)枚举类,只定义一个变量
INSTANCE;
//(2)构造私有
private Singleton2(){
System.out.println("private Singleton3()");
}
//(3)获取枚举常量
private static Singleton2 getInstance(){
return INSTANCE;
}
}
3、懒汉式
- 构造私有
- 提供一个静态私有的成员常量,类型就是单例类型,值为空
- 当调用该方法时才new
- 提供公共的静态方法获取上述的静态成员常量
public class Singleton3 {
//(2)声明静态变量为空
private static Singleton3 INSTANCE = null;
//(1)构造私有
private Singleton3(){
System.out.println("private Singleton1()");
}
//(3)提供公共的静态方法获取上述的静态成员变量
//添加synchronized保证在多线程情况下运行正常
public static synchronized Singleton3 getInstance() {
//(4)调用该方法时再new,通过判断是否为空可控制只创建一个实例
if(INSTANCE == null) {
INSTANCE=new Singleton3();
}
return INSTANCE;
}
}
注意:如果在多线程下,要防止多次创建实例,则在静态方法上添加synchronized,但其实我们只要在第一次调用时保证线程安全就可以,因此此方式的效率比较低,如果要提高效率,可以参考下述两种实现方式。
4、DCL懒汉式-双检索懒汉式
DCL懒汉式是为了保证多线程下运行正常,同时提高效率,也就是在静态方法中加锁之前判断是否已经创建了实例。同时静态变量使用volatile修饰
public class Singleton4 {
//(2)声明静态变量为空
private static volatile Singleton4 INSTANCE = null;//可见性,有序性
//(1)构造私有
private Singleton4(){
System.out.println("private Singleton1()");
}
//(3)提供公共的静态方法获取上述的静态成员变量,调用该方法时再new
public static Singleton4 getInstance() {
//在加锁之前进行判断
if(INSTANCE == null) {//一次检索
synchronized (Singleton4.class){
if (INSTANCE == null){//二次检索
INSTANCE=new Singleton4();
}
}
}
return INSTANCE;
}
}
5、懒汉式内部类单例模式
使用内部类的方式可以保证线程安全,建议使用
public class Singleton5 {
//构造私有
private Singleton5(){
System.out.println("private Singleton5()");
}
//创建内部类,在内部类中新建实例
private static class Holder{
static Singleton5 INSTANCE=new Singleton5();
}
private static Singleton5 getInstance(){
return Holder.INSTANCE;
}
}
二、单例模式在jdk中的体现
- Runtime类是单例模式,饿汉式单例实现
- System类中的有一个Console类型的cons变量,采用DCL懒汉式方式实现
- Collections类中有大量单例模式实现,采用内部类懒汉式实现
单例模式五种实现方式以及在JDK中的体现的更多相关文章
- LFU五种实现方式,从简单到复杂
前言 最近刷力扣题,对于我这种 0 基础来说,真的是脑壳疼啊.这个月我估计都是中等和困难题,没有简单题了. 幸好,力扣上有各种大牛给写题解.看着他们行云流水的代码,真的是羡慕不已.让我印象最深刻的就是 ...
- iOS开发中数组常用的五种遍历方式
随着iOS的不断发展,apple也不断推出性能更高的数组遍历方式,下面将对熟悉的五种遍历方式进行列举. 首先定义一个数组,并获取数组长度 NSArray *array=@[",]; NSIn ...
- Spring事务Transaction配置的五种注入方式详解
Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...
- CacheConcurrencyStrategy五种缓存方式
CacheConcurrencyStrategy有五种缓存方式: CacheConcurrencyStrategy.NONE,不适用,默认 CacheConcurrencyStrategy.REA ...
- IPC五种通讯方式
IPC五种通讯方式 1.管道:速度慢,容量有限,只有父子进程能通讯 2.FIFO:任何进程间都能通讯,但速度慢 3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题 ...
- CSIC_716_20191129【 单例模式 的五种实现方式】
单例模式 单例模式:在确定类中的属性和方法不变时,需要反复调用该类的情况. 让所有通过该类实例化出的对象,都指向同一个内存地址. 优点:节省内存空间. 单例模式有五种表现形式: 1.通过class ...
- JS 跨域问题常见的五种解决方式
一.什么是跨域? 要理解跨域问题,就先理解好概念.跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来 ...
- Java单例模式几种实现方式
在平时的工作.学员的学习以及面试过程中,单例模式作为一种常用的设计模式,会经常被面试官问到,甚至笔试会要求学员现场默写,下面将会就单例模式的实现思路和几种常见的实现方式进行简单的分享. 单例模式,是一 ...
- Flex页面跳转的五种实现方式
Flex页面跳转有很多值得学习的地方,本文向大家介绍一下Flex页面跳转的几种方式,主要包括五种方式,这里为大家一一介绍. AD: 在学习Flex的过程中,你可能会遇到Flex页面跳转的概念,这里 ...
- JavaScript五种继承方式详解
本文抄袭仅供学习http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html 一. 构造函数绑定 ...
随机推荐
- pybind11
fatal error: Python.h: no such file or directory 在使用pybind11时,如果不做调整可能就会出现这样的情况,Python.h一般出现在usr/inc ...
- Linux复习笔记
Linux复习笔记 常识说明 目录结构 Linux以树型结构管理文件,其最上层文件夹为 / ,也就是根目录. 如图所示,图中展示了一部分文件夹的结构: 所有的文件夹都属于根目录的子文件夹. 安装好系统 ...
- [转帖]记一次sst文件损坏修复过程
https://tidb.net/blog/54e388c8 [2023-07-14 14:26:28]应用系统报警删除数据失败,查看日志报Region is unavailable,同时企业微信群也 ...
- [转帖]Linux AWK工作原理
https://www.cnblogs.com/yeyuzhuanjia/p/13967513.html 本篇文章我们主要为大家介绍 AWK 是如何工作的. AWK 工作流程可分为三个部分:1.读输入 ...
- [转帖]解决vCenter6.x由于证书过期问题无法登录
https://www.dinghui.org/vcenter-sts-certificate.html#:~:text=%E8%BF%99%E6%97%B6%E5%80%99%EF%BC%8C%E5 ...
- [转帖]exportfs命令
https://www.cnblogs.com/xzlive/p/9766388.html exportfs命令:功能说明 :NFS共享管理语法格式exportfs [必要参数][选择参数][目录]功 ...
- Redis-rdb-tools与rdr工具学习与使用
Redis-rdb-tools与rdr工具学习与使用 简要说明 rdb工具是python写的一套工具,可以分析dump文件,获取key等信息. rdb其实有一套rdb-profiler工具, 能够导出 ...
- Zabbix6.0的安装与IPMI的简单使用
zabbix简介 1.zabbix的安装与使用 建议使用CentOS8进行部署, 不建议使用CentOS7, rpm包直接部署的话,CentOS8比较容易一些 支持mysql数据库.建议先期部署mys ...
- open,os模块的常用函数
一.open用于读写文件 1.open的基本语法 : open(file,mode,buffering,encoding,errors.........),open中有如下几个参数,一般情况 下我们只 ...
- DPText-DETR: 基于动态点query的场景文本检测,更高更快更鲁棒 | 京东探索研究院
针对场景文本检测任务,近期基于DEtection TRansformer (DETR) 框架预测控制点的研究工作较为活跃.在基于DETR的检测器中,query的构建方式至关重要,现有方法中较为粗糙的位 ...