单件模式——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(单件)—对象创建型模式 几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的.您希望在应用程序中共享数据库句柄,因为在保持连接打开或关 ...
随机推荐
- centos7图形化界面安装后,意外出现Please make your choice from above ['q' to quit | 'c' to continue | 'r' to refresh]
安装完成centos7-GUI后出现如下提示: nitial setup of CentOS Linux (core) ) [x] Creat user ) [!] License informati ...
- [UE4]在AIController中使用行为树
行为树会在Root根下面的每个子节点中从左右到右来回往复循环执行.
- 关于javascript三目
三目运算符能使我们的代码更为简洁,因而包括小编的我也很是青睐它,不过有时候我们给予它更多的希望,小编处于学习阶段,先从笔记开始: (3>1)?console.log(1):console.log ...
- 【Unix网络编程】chapter7套接字选项
7.1 概述 有很多方法来获取和设置影响套接字的选项: getsockopt和setsockopt函数 fcntl函数 ioctl函数 7.2 getsockopt和setsockopt函数 7.3 ...
- 配置Jsp错误页面
配置Jsp错误页面一般我们有2种做法: (1)在页面中用指令进行配置,即page指令的errorPage和isErrorPage:可以使用page指令的errorPage来指定错误页!在当前JSP页面 ...
- 2018 oppo校招前端面试题
1.Es6 2.http请求过程 3.js事件执行流程(蒙蔽中) [默认冒泡,由内到外,] 4.css 样式选择器的优先级 (!important在类选择器和id选择器都可以使用,但不推荐使用) 5. ...
- linux 乌班图 安装pycharm
1.通过vmware安装ubuntu系统2.安装完成后,登录ubuntu,通过普通用户 s14登录,密码redhat3.下载pycharm到ubuntu系统中 -可以通过python -m http. ...
- 微服务、SOA 和 API对比与分析
摘要: 对比微服务架构和面向服务的架构(SOA)是一个敏感的话题,常常引起激烈的争论.本文将介绍这些争论的起源,并分析如何以最佳方式解决它们.然后进一步查看这些概念如何与 API 管理概念结合使用,实 ...
- python-多线程和线程池
import threading # 点击查看它的用法 传统多线程方案会使用“即时创建, 即时销毁”的策略. from multiprocessing.dummy import Pool # 线程池 ...
- python-运算符重载
1. __item__ class X: def __init__(self, data=None): self.data = data or [] # 同样可用于 dict def __setite ...