博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
"围观"设计模式(7)--创建型之单例模式(Singleton Pattern)
阅读量:5124 次
发布时间:2019-06-13

本文共 2963 字,大约阅读时间需要 9 分钟。

单例模式,也叫单子模式,是一种经常使用的软件设计模式。在应用这个模式时,单例对象的必须保证仅仅有一个实例存在。

很多时候整个系统仅仅须要拥有一个的全局对象。这样有利于我们协调系统总体的行为。比方在某个server程序中,该server的配置信息存放在一个文件中。这些配置数据由一个单例对象统一读取。然后服务进程中的其它对象再通过这个单例对象获取这些配置信息。这样的方式简化了在复杂环境下的配置管理。----维基百科(WIKIPEDIA)

个人的理解:

单例模式概念比較简单,他的目的就是仅仅同意出现一个该类的实例,常常在JDBC操作类等处被用到。我在项目中应用到的地方就是用于获取Dao层的类的实例。单例模式有多种实现方式。这里我认知到的有饿汉式、懒汉式、枚举、静态内部类。庆幸这次整理过程。由于又拓展了不少的单例模式的知识。

以下看实际的样例:

懒汉式

public class Singleton01 {	private static Singleton01 singleton = null;		private Singleton01(){}		public static Singleton01 getInstance(){				if(singleton == null)			singleton = new Singleton01();				return singleton;	}}
线程不安全。当多个线程同一时候调用getInstance方法时。都检測到singleton为null,然后就開始创建对象了,这时候就会创建多个实例,而不是一个。

public class Singleton02 {	private static Singleton02 singleton = null;		private Singleton02(){}		public synchronized static Singleton02 getInstance(){				if(singleton == null)			singleton = new Singleton02();				return singleton;	}}
这个样例线程安全了,多个线程同一时候调用的时候也不会创建多个对象实例了。可是不是非常高效,须要多个线程依次的去运行这种方法。

public class Singleton03 {	private static Singleton03 singleton = null;		private Singleton03(){}		public static Singleton03 getInstance(){				if(singleton == null)			synchronized (Singleton03.class) {								if(singleton == null){					singleton = new Singleton03();				}			}						return singleton;	}}
这样的方式被称为Double Check(双重检验),比較经典的设计。为什么要两次呢?先说外面的推断是避免对象已经创建好了之后,就不用再去同步运行创建对象去了,第二个是。防止第一次还没有创建实例的时候,多个线程已经在等待中,这个时候须要进行空的推断。防止后面等待的现场进入之后再次创建实例。

參考了其它人的文章【1】:

singleton = new Singleton()不是原子操作,在JVM中大致做了三件事情:

1. 给instance分配内存。

2. 通过其构造函数初始化成员变量。

3. 将instance指向分配的内存空间。

(运行完instance就不是null了)。

可是在JVM编译器中存在指令又一次排序的优化,终于的运行顺序是1-2-3或者1-3-2。假设是1-3-2的话。那么在3运行完成,2运行之前,线程A被线程B抢断的话,instance非空,线程B会直接返回instance,这个时候。直接使用就会报错。

给出的解决方案(使用volatilekeyword屏蔽重排序)是:

public class Singleton03 {	private volatile static Singleton03 singleton = null;		private Singleton03(){}		public static Singleton03 getInstance(){				if(singleton == null)			synchronized (Singleton03.class) {								if(singleton == null){					singleton = new Singleton03();				}			}						return singleton;	}}

饿汉式

public class Singleton04 {	private static final Singleton04 singleton = new Singleton04();		private Singleton04(){	}		public static Singleton04 getInstance(){		return singleton;	}}
这样的方式是线程安全的,只是不足的一点是,即使没有调用getInstance方法。也会产生他的实例。之前的懒汉式的方式是懒载入的思想,在须要的时候创建。

静态内部类

public class Singleton05 {	private static class Singleton{		private static final Singleton05 instance = new Singleton05();	}		private Singleton05(){	}		public Singleton05 getInstance(){		return Singleton.instance;	}}
採用了静态内部类的方式,私有的静态内部类,外部无法訪问。类似于饿汉式的形式,可是在此基础上进行了改进,饿汉式是使用的内部属性,而这个是
使用的静态内部类的常量。

枚举

神一样的设计,使用枚举实现单例模式的几个原因:

1. 自由序列化

2. 线程安全

3. 保证仅仅有一个实例。

public enum Singleton06 {	INSTANCE;		private Singleton06(){	}		public void print(){		System.out.println("Enum Singleton!");	}}
调用:

Singleton06.INSTANCE.print();

代码下载

參考

【1】 http://wuchong.me/blog/2014/08/28/how-to-correctly-write-singleton-pattern/

转载于:https://www.cnblogs.com/blfbuaa/p/7269496.html

你可能感兴趣的文章
class-dump获取iOS私有api
查看>>
java实例练习——基于TCP/IP协议的多客户端通信
查看>>
图片加到json中,提交到服务器端处理异常问题。
查看>>
[Poi2011]Tree Rotations线段树合并
查看>>
Ubuntu 12.04(32位)安装Oracle 11g(32位)全过程以及几乎所有问题的解决办法
查看>>
Timer更新UI的合理办法
查看>>
jquery中对动态生成的标签响应click事件(二)…与ajax交互使用
查看>>
推荐几个.NET开源图表组件 [转]
查看>>
脚本两则--用于快速部署HADOOP,SPARK这些(特别是VM虚拟机模板部署出来的)。。...
查看>>
用JQUERY为INPUT的TXT类型赋值及取值操作
查看>>
(视频) 《快速创建网站》 3.2 WordPress多站点及Azure在线代码编辑器 - 扔掉你的ftp工具吧,修改代码全部云端搞定...
查看>>
(转) 一步一步学习ASP.NET 5 (四)- ASP.NET MVC 6四大特性
查看>>
Python学习笔记——基础篇【第六周】——hashlib模块
查看>>
python的collection系列-默认字典(defaultdict)
查看>>
Noip 2014酱油记+简要题解
查看>>
loadrunner学习记录一
查看>>
转为win64后, MS的lib问题
查看>>
jQuery操作cookie
查看>>
编码解码错误
查看>>
HDU-1008
查看>>