HeadFirst设计模式之单例模式
一、
1.The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.
2.
3.
二、例子一:线程不安全
package headfirst.designpatterns.singleton.chocolate;
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static ChocolateBoiler uniqueInstance;
private ChocolateBoiler() {
empty = true;
boiled = false;
}
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null) {
System.out.println("Creating unique instance of Chocolate Boiler");
uniqueInstance = new ChocolateBoiler();
}
System.out.println("Returning instance of Chocolate Boiler");
return uniqueInstance;
}
public void fill() {
if (isEmpty()) {
empty = false;
boiled = false;
// fill the boiler with a milk/chocolate mixture
}
}
public void drain() {
if (!isEmpty() && isBoiled()) {
// drain the boiled milk and chocolate
empty = true;
}
}
public void boil() {
if (!isEmpty() && !isBoiled()) {
// bring the contents to a boil
boiled = true;
}
}
public boolean isEmpty() {
return empty;
}
public boolean isBoiled() {
return boiled;
}
}
三、加上synchronized
直接在getInstance()方法中加上synchronized虽然线程安全,但得不尝失。因为理想的情况是只在第一次访问getInstance时才需要同步,以后的访问不用同步,因为已经有了instance了
package headfirst.designpatterns.singleton.threadsafe;
public class Singleton {
private static Singleton uniqueInstance;
// other useful instance variables here
private Singleton() {}
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// other useful methods here
public String getDescription() {
return "I'm a thread safe Singleton!";
}
}
四、用饿汉式解决线程安全(用static ,JVM会在任何线程访问前初始化变量)
package headfirst.designpatterns.singleton.stat;
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return uniqueInstance;
}
// other useful methods here
public String getDescription() {
return "I'm a statically initialized Singleton!";
}
}
Using this approach, we rely on the JVM to create the unique instance of the Singleton when the class is loaded. The JVM guarantees that the instance will be created before any thread accesses the static uniqueInstance variable.
五、用双重检查
package headfirst.designpatterns.singleton.dcl; //
// Danger! This implementation of Singleton not
// guaranteed to work prior to Java 5
// public class Singleton {
private volatile static Singleton uniqueInstance; private Singleton() {} public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
With double-checked locking, we first check to see if an instance is created, and if not, THEN we synchronize. This way, we only synchronize the first time through, just what we want.
The volatile keyword ensures that multiple threads handle the uniqueInstance variable correctly when it is being initialized to the Singleton instance.
六、
1.
Q: What about class loaders?
I heard there is a chance that two class loaders could each end up with their own instance of Singleton.A: Yes, that is true as each class loader defines a namespace. If you have two or more classloaders, you can load the same class multiple times (once in each classloader). Now, if that class happens to be a Singleton, then since we have more than one version of the class, we also have more than one instance of the Singleton. So, if you are using multiple classloaders
and Singletons, be careful. One way around this problem is to specify the classloader yourself.
2.
I still don’t totally understand why global variables are worse than a Singleton.
A: In Java, global variables are basically static references to objects.There are a couple of disadvantages to using global variables in this manner. We’ve already mentioned one: the issue of lazy versus eager instantiation. But we need to keep in mind the intent of the pattern: to ensure only one instance of a class exists and to provide global access. A
global variable can provide the latter,but not the former. Global variables also tend to encourage developers
to pollute the namespace with lots of global references to small objects.Singletons don’t encourage this in the same way, but can be abused nonetheless.
HeadFirst设计模式之单例模式的更多相关文章
- Delphi 设计模式:《HeadFirst设计模式》Delphi2007代码---单例模式之ChocolateBoiler[转]
1 2{<HeadFirst设计模式>之单例模式 } 3{ 编译工具: Delphi2007 for win32 } 4{ E-Mail : guzh-0417@163.com ...
- headfirst设计模式(5)—工厂模式体系分析及抽象工厂模式
先编一个这么久不写的理由 上周我终于鼓起勇气翻开了headfirst设计模式这本书,看看自己下一个设计模式要写个啥,然后,我终于知道我为啥这么久都没写设计模式了,headfirst的这个抽象工厂模式, ...
- 设计模式之单例模式(Singleton)
设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...
- GJM : C#设计模式(1)——单例模式
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- 每天一个设计模式-4 单例模式(Singleton)
每天一个设计模式-4 单例模式(Singleton) 1.实际生活的例子 有一天,你的自行车的某个螺丝钉松了,修车铺离你家比较远,而附近的五金店有卖扳手:因此,你决定去五金店买一个扳手,自己把螺丝钉固 ...
- 设计模式之单例模式的简单demo
/* * 设计模式之单例模式的简单demo */ class Single { /* * 创建一个本类对象. * 和get/set方法思想一样,类不能直接调用对象 * 所以用private限制权限 * ...
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 10月27日PHP加载类、设计模式(单例模式和工厂模式)、面向对象的六大原则
加载类可以使用include.require.require_once三种中的任意一种,每个关键字都有两种方法,但是这种方法的缺点是需要加载多少个php文件,就要写多少个加载类的方法.一般也就需要加载 ...
随机推荐
- C++与Lua交互(五)
引言 要将C++中的对象类型映射到Lua中,就不得不要先了解Lua面向对象的机制.在这里,我们先看一下Lua面向对象的实现基础--metatable,再以此实现C++对象到Lua的映射. Lua面向对 ...
- 停车场管理软件附带源代码 J2EE服务端+android客户端
该源码是停车场管理软件附带源代码 J2EE服务端+android客户端,也是一套停车场管理车辆进出的管理软,喜欢的朋友可以看看吧. 应用的后台管理主要功能介绍:1 机构管理 ,机构有从属管理< ...
- Linux rar
http://www.vpsyou.com/2010/06/15/to-extract-rar-centos.html wget http://www.rarsoft.com/rar/rarlinux ...
- ASP.net中导出Excel的简单方法介绍
下面介绍一种ASP.net中导出Excel的简单方法 先上代码:前台代码如下(这是自己项目里面写的一点代码先贴出来吧) <div id="export" runat=&quo ...
- 写了个Linux包过滤防火墙
花几天写了个so easy的Linux包过滤防火墙,估计实际意义不是很大.防火墙包括用户态执行程序和内核模块,内核模块完全可以用iptable代替.由于在编写的过程一开始写的是内核模块所以就直接用上来 ...
- 禁止指定目录执行php文件
我们设置网站权限的时候,有些目录不得不设置让http服务器有写入权限,这样安全隐患就来了.比如discuz x2的 data目录,这个必须要有写入限,论坛才能正常运行,但有的黑客可能就会利用这个目录上 ...
- ECSHOP 支付宝发货确认接口,记录支付宝返回的交易号
1,在order_info 数据表尾添加trade_no 字段 数据表尾怎么添加trade_no 字段 ECSHOP为了支付宝发货确认接口,需要记录支付宝返回的交易号 1,在order_info 数据 ...
- Python字符串内建处理函数
#coding=utf-8 __author__ = 'Administrator' # 字符串处理函数 s1 = "study python string function , I lov ...
- Android:使用命令行工具adb、mksdcard等
有一些Android的工具需要在命令行的环境中运行,只是可以选择Windows的开始->运行,键入cmd并确定,进入命令行的界面中运行.主要的命令行工具包括adb和mksdcard等.命令行的工 ...
- fedora -- java多版本切换
一般java开发时会下载多个版本的SDK,所以需要多个版本中进行切换 1. 设置JAVA_HOME环境变量需要打开.bashrc文件 2. 安装时使用alternatives将不同版本的java连接到 ...