单件模式——Head First
一、定义
单件模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。
二、适用性
1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。(《设计模式:可复用面向对象软件的基础》中这句话暂不能理解)
三、类图

四、经典实现
public class Singleton {
private static Singleton uniqueInstance;
//其他有用的实例变量
//构造方法是私有的,所以在类外不能new出多个实例
private Singleton(){
//初始化其他实例变量
}
public static Singleton getInstance(){
if (uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
//其他的有用方法
}
如果不需要这个实例,它就永远不会产生,这就是“延迟实例化”(lazy instantiaze)。
五、处理多线程
在多线程下,上述经典实现中getInstance方法可能会返回不同的实例(两个线程同时判断出uniqueInstance为null,从而产生两个不同的实例)。针对这种情况,我们有以下三种方法。
1、将getInstance变成同步方法
//通过增加sychronized关键字到getInstance方法中,迫使每个线程在进入这个方法之前,要先等别的线程离开该方法。也即,不会有两个线程可以同时进入这个方法。
public static synchronized Singleton getInstance(){
if (uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
缺点:只有第一次执行getInstance时才需要同步,之后每次调用getInstance方法,同步都是一种累赘,从而拖垮性能。
2、“急切”创建实例
public class Singleton {
//在静态初始化器(static initializer)中创建单件,保证线程安全(thread safe)
private static Singleton uniqueInstance=new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
//已经有了实例,直接使用它
return uniqueInstance;
}
}
缺点:如果这个对象非常耗费资源,而在程序的执行过程中并没有使用到它,那就造成并资源的浪费。
3、用“双重检查加锁”,在getInstance()中减少使用同步
public class Singleton {
//volatile关键词确保:当uniqueInstance变量被初始化成Singleton实例时,多个线程正确地处理uniqueInstance变量
private volatile static Singleton uniqueInstance;
private Singleton(){
}
public static Singleton getInstance(){
//检查实例,如果不存在,就进入同步区块。只有第一次才彻底执行这里的代码
if(uniqueInstance==null){
synchronized(Singleton.class){
//进入区块后,再检查一次。如果仍是null,才创建实例
if(uniqueInstance==null){
uniqueInstance=new Singleton();
}
}
}
return uniqueInstance;
}
}
缺点:版本兼容问题。在1.4及更早版本的java中,许多JVM对于volatile关键字的实现会导致双重检查加锁的失效。
六、其他
每个类加载器都定义了一个命名空间,如果有两个以上的类加载器,不同的类加载器可能会加载同一个类,从整个程序来看,同一个类会被加载多次。如果这样的事情发生在单件上,就会产生多个单件并存的怪异现象。解决方法:自行指定类加载器,并指定同一个类加载器。
单例模式会遭到破坏:
- 反射:调用setAccessible(true)方法,关掉安全检查,调用私有构造器。预防:修改构造器,让它在被要求创建第二个实例的时候抛出异常。
- 序列化和反序列化:对象序列化后再反序列化时, 会有一个新的对象被克隆出来。预防:加入readResolve()回调方法,返回指定的对象。
单件模式——Head First的更多相关文章
- Java设计模式——线程安全的单件模式
单件模式,也称单例模式,用以创建独一无二的.只能有一个实例的对象. 单件模式的类图是所有模式的类图中最简单的--只有一个类.尽管从类设计的视角来看单件模式很简单,但是实现上还是会遇到一些问题,本文着重 ...
- C#设计模式——单件模式
一.为何需要单件模式 需求 我们开发了一个大型的项目,其中存在许多的工具类.但是其中很多的工具类我们并不是经常使用得到,甚至 一次都不会使用.但是这些工具类都是静态的类,会消耗很多的内存,即使一次都不 ...
- 关于C++单件模式释放对象
http://blog.csdn.net/windboyzsj/article/details/2790485 最近接触的一个项目要用到单件模式,我像往常一样哒哒(敲击键盘ing)一个单件模式的典型结 ...
- C#设计模式——单件模式(Singleton Pattern)
一.概述在软件开发过程中,我们有时候需要保证一个类仅有一个实例,比如在一个电脑用户下只能运行一个outlook实例.这时就需要用到单件模式.二.单件模式单件模式保证一个类仅有一个实例,并提供一个访问它 ...
- [设计模式] javascript 之 单件模式
单件模式说明 1. 说明:单件模式,就是静态化的访问中已经实例化的对象,这个对象只能通过一个唯一的入口访问,已经实例或待实例化的对象:面向对象语言如Java, .Net C#这样的服务端动态语言里,能 ...
- 【设计模式】单件模式(Singleton)--各类单件模式的比较
单件模式 确保一个类只有一个实例,并提供一个安全的访问点. 线程安全+延时初始化+高性能(使用:延时初始化占位符模式) ------测试----------- 线程安全+[非]延时初始化 线程安全+延 ...
- .NET设计模式(2):单件模式(Singleton Pattern)
转载:http://terrylee.cnblogs.com/archive/2005/12/09/293509.html 单件模式(Singleton Pattern) --.NET设计模式系列之二 ...
- 单件模式Singleton来控制窗体被重复或多次打开
本文转载:http://blog.csdn.net/a0700746/article/details/4473796 一般在百度搜一下,会出来一下内容,看来很好用.Singleton很方便的一个用处就 ...
- NET设计模式(2):单件模式(Singleton Pattern)[转载]
单件模式(Singleton Pattern) ——.NET设计模式系列之二 Terrylee,2005年12月07日 概述 Singleton模式要求一个类有且仅有一个实例,并且提供了一个全局的访问 ...
- 设计模式(二)单件模式Singleton(创建型)
SINGLETON(单件)—对象创建型模式 几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的.您希望在应用程序中共享数据库句柄,因为在保持连接打开或关 ...
随机推荐
- [UE4]让机器人开枪射击
- CAS锁相关讲解
感谢GOOGLE强大的搜索,借此挖苦下百度,依靠百度什么都学习不到! 参考文档: http://www.blogjava.net/xylz/archive/2010/07/04/325206.html ...
- Css学习(4)
文档流(标准流) 元素自上而下,自左而右,块元素独占一行,行内元素在一行上显示,碰到父集元素的边框换行. 浮动布局 float: left | right 特点: ★元素浮动之后不占据原来的 ...
- 优化:js 逻辑运算符优化
运算符的代码优化,可以精简代码,提高代码可读性 下面主要讨论下逻辑运算符与 &&, 或||. 示例: 假设对成长速度显示规定如下: 成长速度为5显示1个箭头: 成长速度为10显示2个箭 ...
- mysql 之审计 init-connect+binlog完成审计功能
mysql基于init-connect+binlog完成审计功能 目前社区版本的mysql的审计功能还是比较弱的,基于插件的审计目前存在于Mysql的企业版.Percona和MariaDB上,但是my ...
- (error) MOVED 5798 172.17.0.3:6379
登录没有启动集群模式(即缺少了那个"-c"): redis-cli -c -h yourhost -p yourpost
- 分段覆盖率TPR
黑产监控中,需要尽可能做到尽可能少的误伤和尽可能准确地探测,可以选择“在FPR较低时的TPR加权平均值”作为平均指标. 根据混淆矩阵计算TPR(覆盖率)和FPR(打扰率): 覆盖率:TPR = TP ...
- sklearn不同数量的训练集在测试集上的表现的曲线刻画
def plot_learning_curve(estimator,X,y,cv=5,train_sizes=[0.1,0.3,0.5,0.7,0.8,0.9]): """ ...
- beautifulSoup基本用法及find选择器
总结来源于官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#find-all 示例代码段 html_do ...
- JavaWeb项目中web.xml有关servlet的基本配置
JavaWeb项目中web.xml有关servlet的基本配置: 我们注意到,tomcat下的conf中也有一个web.xml文件,没错的,所有的JavaWeb项目中web.xml都继承自服务器下的w ...