单例模式五种实现方式以及在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 一. 构造函数绑定 ...
随机推荐
- 0xGame 2023【WEEK2】Crypto全解
中间的那个人 题目信息 from secret import flag from Crypto.Util.number import * from Crypto.Cipher import AES f ...
- tomcat 一闪而过 ( 解决方案 )
配置JAVA_HOME,注意变量值是jdk的主目录,不是bin目录,并且不要加分号
- Go-使用本地时间解析时间字符串
字符串 ==> time.Time package main import ( "fmt" "log" "time" ) func m ...
- [转帖]How fast are Unix domain sockets?
https://blog.myhro.info/2017/01/how-fast-are-unix-domain-sockets Jan 3, 2017 • Tiago Ilieve Warning: ...
- [转帖]数据可视化之redash(支持43种数据源) (转自https://anjia0532.github.io/2019/07/08/redash/)
https://www.cnblogs.com/a00ium/p/13177272.html 人类都是视觉动物,讲究一图胜千言.如果没了可视化,那么你在跟领导汇报工作时,很大程度会鸡同鸭讲.其实 ex ...
- [转帖]Linux实用技巧——find查找指定时间内修改过的文件或目录
https://cloud.tencent.com/developer/article/1694949 解决方案 例:查找出五分钟内修改过的文件 [root@mobius ~]$ find ./* - ...
- [转帖]iostat相关参数说明——await:平均每次设备I/O操作的等待时间 (毫秒),如果%util接近 100%,说明产生的I/O请求太多
https://www.cnblogs.com/bonelee/p/6323587.html iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动 ...
- 强化学习从基础到进阶-常见问题和面试必知必答[4]::深度Q网络-DQN、double DQN、经验回放、rainbow、分布式DQN
强化学习从基础到进阶-常见问题和面试必知必答[4]::深度Q网络-DQN.double DQN.经验回放.rainbow.分布式DQN 1.核心词汇 深度Q网络(deep Q-network,DQN) ...
- 【一】gym环境安装以及安装遇到的错误解决
相关文章: [一]gym环境安装以及安装遇到的错误解决 [二]gym初次入门一学就会-简明教程 [三]gym简单画图 [四]gym搭建自己的环境,全网最详细版本,3分钟你就学会了! [五]gym搭建自 ...
- 2.2 Windows驱动开发:内核自旋锁结构
提到自旋锁那就必须要说链表,在上一篇<内核中的链表与结构体>文章中简单实用链表结构来存储进程信息列表,相信读者应该已经理解了内核链表的基本使用,本篇文章将讲解自旋锁的简单应用,自旋锁是为了 ...