Head First 设计模式 第5章 单例模式
第5章 单例模式
1、定义:确保一个类只有一个实例,并为其创建访问点。
2、单例模式的类图:
对应的单例模式的代码:
package com.ek.singleton;
/**
* @包名 com.ek.singleton
* @文件名 Singleton.java
* @作者 edi_kai
* @创建日期 2015年8月25日
* @版本 V 1.0
* @描述
*/
public class Singleton { public static Singleton uniqueSingleton; private Singleton() {
} public static Singleton getInstance() {
if (null == uniqueSingleton) { //确保返回的是同一个对象
uniqueSingleton = new Singleton();
}
return uniqueSingleton;
}
}
这样的单例模式真的没问题吗?当然有。当有两个线程同时调用getInstance方法时,就有可能返回两个Singleton对象。
那么,我们该如何解决这个问题呢?将方法getInstance设置成线程同步的,如下:
package com.ek.singleton;
/**
* @包名 com.ek.singleton
* @文件名 Singleton.java
* @作者 edi_kai
* @创建日期 2015年8月25日
* @版本 V 1.0
* @描述
*/
public class Singleton { public static Singleton uniqueSingleton; private Singleton() {
} public static synchronized Singleton getInstance() {
if (null == uniqueSingleton) {
uniqueSingleton = new Singleton();
}
return uniqueSingleton;
}
}
这是我们设置成线程同步之后的代码,这样可以避免上面说的问题,但是又引入了新的问题:同步一个方法会使效率降低100倍,如果getInstance方法使用比较频繁,我们得需要考虑其他方法来解决问题。
看下面的代码:
package com.ek.singleton;
/**
* @包名 com.ek.singleton
* @文件名 Singleton.java
* @作者 edi_kai
* @创建日期 2015年8月25日
* @版本 V 1.0
* @描述
*/
public class Singleton { public static Singleton uniqueSingleton = new Singleton(); private Singleton() {
} public static Singleton getInstance() {
return uniqueSingleton;
}
}
这里我们直接在静态初始化器中实例化对象,这样JVM在加载这个类的时候,会马上创建这个对象,保证了唯一性。存在的问题是:只要JVM加载该类,对象就会被实例化,不管现在我们是不是需要这个实例化对象。
那么让我们来看最后一种方法,如下:
package com.ek.singleton;
/**
* @包名 com.ek.singleton
* @文件名 Singleton.java
* @作者 edi_kai
* @创建日期 2015年8月25日
* @版本 V 1.0
* @描述
*/
public class Singleton { public volatile static Singleton uniqueSingleton; private Singleton() {
} public static Singleton getInstance() {
if (null == uniqueSingleton) {
synchronized (Singleton.class) {//只有在第一次实例化对象的时候会同步,即便调用比较频繁,也不会影响性能
if (null == uniqueSingleton) {
uniqueSingleton = new Singleton();
}
}
}
return uniqueSingleton;
}
}
这种方式其实就是最理想的方式,其中volatile关键字确保当uniqueSingleton变量被初始化成Singleton实例时,多个线程可以正确的处理uniqueSingleton变量。该方式也有一个问题,那就是volatile关键字需要JDK 1.4以上才支持,在1.4及以下版本中被忽略了,(/ □ \)。
好了,到这里单例模式我们就介绍完了,一定要根据自己的实际环境来确定使用哪一种方式的来实现单例模式哦....
谢谢阅读
转载请注明出处,谢谢!
Head First 设计模式 第5章 单例模式的更多相关文章
- JAVA设计模式——第 3 章 单例模式【Singleton Pattern】(转)
这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此的广泛,如此的有人缘,单例就是单一.独苗的意思,那什么是独一份呢?你的思维是独一份,除此之外还有什么不能山寨的呢?我们举个比较难复制的 ...
- 设计模式之第0章-单例模式(Java实现)
设计模式之第0章-单例模式(Java实现) 当当当当~首先有请最简单的单例模式登场,先来个自我介绍吧 单例模式之自我介绍 我,单例模式(Singleton Pattern)是一个比较简单的模式,我的定 ...
- 第1章 单例模式(Single Pattern)
原文 第1章 单例模式(Single Pattern) 单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点. 一.常用模式: 1 ...
- Java多线程编程核心技术-第6章-单例模式与多线程-读书笔记
第 6 章 单例模式与多线程 本章主要内容 如何使单例模式遇到多线程是安全的.正确的. 6.1 立即加载 / “饿汉模式” 什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就 ...
- Java并发程序设计(八)设计模式与并发之单例模式
设计模式与并发之单例模式 简单的单例实现: public class Singleton { private Singleton(){ System.out.println("Creatin ...
- 设计模式之序章-UML类图那点事儿
设计模式之序-UML类图那点事儿 序 打14年年底就像写那么一个系列,用于讲设计模式的,代码基于JAVA语言,最早接触设计模式是大一还是大二来着,那时候网上有人给推荐书,其中就有设计模式,当时给我推荐 ...
- 设计模式(一)单例模式:创建模式 ASPNET CORE WEB 应用程序的启动 当项目中 没有STARTUP.CS 类如何设置启动 配置等等
设计模式(一)单例模式:创建模式 先聊一下关于设计的几个原则(1)单一原则(SRP):一个类应该仅有一个引起它变化的原因 :意思就是 (一个类,最好只负责一件事情,并且只有一个引起它变化的原因(2)开 ...
- [Python设计模式] 第21章 计划生育——单例模式
github地址:https://github.com/cheesezh/python_design_patterns 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式 ...
- headfirst设计模式(6)—单例模式
前言 这一章的课题看起来就很和蔼可亲了,比起前面绕的我不要不要的工厂模式,那感觉真是太好了,但是正是因为简单,那么问题就来了,我怎么才能把这个东西叙述清楚?怎么样才能老少咸宜呢? 如何能够在把这个东西 ...
随机推荐
- Python 编码错误的本质原因
转载自:https://foofish.net/python-unicode-error.html 不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久的新贵,你一定遇到过Uni ...
- mysql in 和 not in 语句用法
1.mysql in语句 select * from tb_name where id in (10,12,15,16);2.mysql not in 语句 select * from tb_name ...
- JAVA基础——编程练习(二)
JAVA编程练习(二) 今天我为了巩固之前的java基础知识的学习,再次进行实战演习,编写了一个小小的java控制台程序,主要是运用java面向对象的思想来完成这个小项目. 一.项目背景介绍 根据所学 ...
- seajs源码阅读
乘着周日有点时间,阅读一下玉伯大神的源码. seajs的源码写得真的很好,很是佩服,工整美观不愧是大神,造福百姓. 说起seajs不得不说,AMD和CMD的区别. CMD 推崇依赖就近,AMD 推崇 ...
- C#工作笔记
没想到一个Java后端开发还要负责C#桌面程序,我感觉有点方.不过方归方,活还是要干的.简单记录下学到的一些知识点. 1.引用API函数 namespace Demo { class MyUtil { ...
- ReactiveCocoa源码解析(六) SignalProtocol的take(first)与collect()延展实现
上篇博客我们聊了observe().map().filter()延展函数的具体实现方式以及使用方式.我们在之前的博客中已经聊过,Signal的主要功能是位于SignalProtocol的协议延展中的, ...
- 《Java编程思想》第一二章
前段时间一直通过网络教程学习Java基础,把面向对象部分学完之后本来打算继续深入学习,但是感觉自己操之过急了,基础根本不够扎实,所以入手了一本<Java编程思想>,希望先把基础打好,再深入 ...
- 自定义七天签到View
github传送车走你 https://github.com/guanhaoran/signin 因为这个View 是我很早之前写的,这些注释也是我今天刚想往github上传的时候 临时加的 有的注 ...
- CSS边框(圆角、阴影、背景图片)
1.圆角 border-radius是向元素添加圆角边框. 使用方法: border-radius:10px; /* 所有角都使用半径为10px的圆角 */ border-radius: 5px 4 ...
- zookeeper+dubbo简单使用
首先下载zookeeper,直接百度官网下载即可! 下载完之后,把cfg配置文件改名为zoo.cfg,如下: 在bin目录下启动zkServer即可! 项目结构: 简单讲解:首先dubbo是一个mav ...