单件模式——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(单件)—对象创建型模式 几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的.您希望在应用程序中共享数据库句柄,因为在保持连接打开或关 ...
随机推荐
- python之路——4
王二学习python的笔记以及记录,如有雷同,那也没事,欢迎交流,wx:wyb199594 复习 1.ASCII: 字母 数字 特殊字符,1个字节(8位)表示 Unicode :16位 两个字节 一个 ...
- IPSec
一. +IPSec(IP Security)Internet 协议安全性 是IFTF制定的为保证在Internet上传送数据的安全保密性能的框架协议 +IPSec包括报文验证头协议AH(协议号51)和 ...
- [UE4]C++中SpawnActor用法(动态创建Actor)
转自:http://aigo.iteye.com/blog/2270177 C++中创建一个Level并添加的Runtime当中 C++中Spawn一个基于蓝图的Actor https://answe ...
- sas infile 控制导入长度
/*尝试使用infile解决uesrname的录入只能存储一单位的问题*/data TestPayRecord2;infile "D:\开发工具\购买记录表.csv" dlm='2 ...
- 第11课 std::bind和std::function(2)_std::bind绑定器
1. 温故知新:std::bind1st和std::bind2nd (1)bind1st.bind2nd首先它们都是函数模板,用于将参数绑定到可调用对象(如函数.仿函数等)的第1个或第2个参数上. ( ...
- spark2.3.0 配置spark sql 操作hive
spark可以通过读取hive的元数据来兼容hive,读取hive的表数据,然后在spark引擎中进行sql统计分析,从而,通过spark sql与hive结合实现数据分析将成为一种最佳实践.配置步骤 ...
- 安装memcache集群管理工具
安装memcache集群管理工具magent 一.安装libevent tar xf libevent--stable.tar.gz cd libevent- ./configure --prefix ...
- Android被忽略的tools
自动生成的布局xml文件,很多都带有tools字样:但是大部分都被我们删除了: 其实它的作用是让我们这些开发者预览用的,十分的方便: 事例一个TextView: <TextView androi ...
- linux中Centos7搭建lnmp环境
1.安装yum yum update 2.安装nginx源: yum localinstall http://nginx.org/packages/centos/7/noarch/RPMS/nginx ...
- QQ聊天字体选择
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...