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文件,就要写多少个加载类的方法.一般也就需要加载 ...
随机推荐
- emacs_1
--> 正在处理依赖关系 perl(VMS::Filespec),它被软件包 perl-PathTools-3.2701-1.el5.rf.x86_64 需要---> 软件包 perl-p ...
- 指针与strncpy---内存
指针的形式的赋值和strncpy的赋值 e.SetAttr("Amt", ToString(dAmt) ); e.SetAttr("Amt", sAm ...
- 多文件上传 iOS功能
多文件上传 iOS功能,原文来自ios教程网整理的,大家可以看看演示:ios.662p.com ,喜欢的朋友可以看看我的博客吧. NSURL* url = [NSURL URLWithString:@ ...
- SQL 远程过程调用失败【0x800706be】或正在关闭 【0x80041033】解决方法
在SQL Server 配置管理器中出现[远程过程调用失败.[0x800706be]]或者[正在关闭 [0x80041033]]错误,如图所示 上网查找发现时SQL2008与VS2012或VS2013 ...
- C# and Redis,安装作为服务
本文主要讲述的是如何使用C#语言来进行Redis分布式缓存的程序编写.首先,需要从github下载最新的32/64位安装(下载地址),解压后根据自己机器的实际情况选择32位或者64位,例如:我机器是6 ...
- js给数字加三位一逗号间隔的两种方法(面试题)
方法一: <script type= "text/javascript"> //保留三位小数,toLocaleString() 方法可把一个 Number 对象转换 ...
- Cassandra1.2文档学习(18)—— CQL数据模型(下)
三.集合列 CQL 3 引入了一下集合类型: •set •list •map 在关系型数据库中,允许用户拥有多个email地址,你可以创建一个email_addresses表与users表存在一个多对 ...
- C盘清理大作战
C盘会随着使用时间慢慢变满(即使你不在C盘装程序),下面就记录几个C盘清理的方法: 1.使用清理软件清理C盘(360卫视,腾讯管家) 2.转移虚拟内存:计算机右键属性——高级管理设置——高级——性能- ...
- 装tortoiseSVN时遇到的坑
今天给新电脑配置开发环境,线上SVN地址申请权限以后,在本地装了tortoiseSVN,可是安装了以后死活打不开.明明浏览器里可以打开SVN地址,但是tortoiseSVN的浏览器里却打不开,摆弄了很 ...
- Ubuntu虚拟机与Window、Arm的通信
Ubuntu虚拟机与Window的通信安装有Ubuntu14.04的虚拟机VMware,将虚拟机的网络适配器配置成NAT类型(默认使用VMnet8进行通信),此时将Ubuntu的IP地址设置成与VMn ...