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)—单例模式
前言 这一章的课题看起来就很和蔼可亲了,比起前面绕的我不要不要的工厂模式,那感觉真是太好了,但是正是因为简单,那么问题就来了,我怎么才能把这个东西叙述清楚?怎么样才能老少咸宜呢? 如何能够在把这个东西 ...
随机推荐
- eclipse 和 jdk的位数不同
如果eclipse 和 jdk的位数不同,如一个64Bit一个32位,不需要修改环境变量,只需要在eclipse根目录的eclipse.ini文件中第一行加入:-vmD:\Program Files\ ...
- php二进制流文件
<?php $img_file = 'test.png'; // $fp = fopen($img_file, 'rb'); // $content = fread($fp, filesize( ...
- 【Android Developers Training】 92. 序言:使用同步适配器传输数据
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- EJB系列 - EJB高级概念
本人博客文章网址:https://www.peretang.com/ejb-advanced-concepts/ EJB内幕 幕后的EJB:容器会为每一个bean实例自动生成称为EJB对象的代理, 由 ...
- Css绘制形状
前言:终于我的大一生活结束了,迎来了愉快的暑假,大家都开始了各自的忙碌.一直忙着一些项目的事情,终于决定今天要更新一篇博客了,对上一阶段的学习做简单的总结. 这次我主要总结一下用Css绘制各种形状的技 ...
- 《JavaScript高级程序设计》 -- 变量、作用域和内存问题(二)
1.基本类型与引用类型 基本类型:值保存在变量中 (Number.String.Boolean.Undefined.Null).在内存中占据固定大小空间,被保存在栈内存中 引用类型:值是保存在内存中的 ...
- linux中日志介绍
linux日志 linux日志大多是以明文存储,一般存储在/var/log目录中,linux系统中主要有三个日志子系统:连接时间日志,进程统计日志,错误日志. 连接时间日志 连接时间日志是有多个程序执 ...
- FineBI如何在web页面中嵌入式集成
1. API嵌入集成 1.1 描述 FineBI是基于B/S架构的浏览器/服务器模式,现在用户开发的系统基本上趋向于B/S架构的浏览器/服务器模式,因此有些页面完全可以直接采用web页面嵌入式集成的简 ...
- C++第二篇--访问控制
C++第二篇--访问控制 1. 引入 上一篇博文中从结构体引到了类,类当中不仅有数据成员还有一些函数,这些函数被称为成员函数.今天介绍新的内容,类当中的访问控制. 2. 访问控制 当你不添加任何声明, ...
- Python 批量翻译 使用有道api;
妹子是做翻译相关的,遇到个问题,要求得到句子中的所有单词的 音标; 有道翻译只能对单个单词翻译音标,不能对多个单词或者句子段落翻译音标; 手工一个一个翻的话那就要累死人了.....于是就让我写个翻译音 ...