单例模式,也叫单子模式,是一种经常使用的软件设计模式。在应用这个模式时,单例对象的类必须保证仅仅有一个实例存在。

很多时候整个系统仅仅须要拥有一个的全局对象。这样有利于我们协调系统总体的行为。比方在某个server程序中,该server的配置信息存放在一个文件中。这些配置数据由一个单例对象统一读取。然后服务进程中的其它对象再通过这个单例对象获取这些配置信息。这样的方式简化了在复杂环境下的配置管理。----维基百科(WIKIPEDIA)

个人的理解:

单例模式概念比較简单,他的目的就是仅仅同意出现一个该类的实例,常常在JDBC操作类等处被用到。我在项目中应用到的地方就是用于获取Dao层的类的实例。单例模式有多种实现方式。这里我认知到的有饿汉式、懒汉式、枚举、静态内部类。庆幸这次整理过程。由于又拓展了不少的单例模式的知识。

以下看实际的样例:

懒汉式



</pre><span style="font-size:18px;"><span style="font-size:12px;"></span></span><pre name="code" class="java">public class Singleton01 {

	private static Singleton01 singleton = null;

	private Singleton01(){}

	public static Singleton01 getInstance(){

		if(singleton == null)
singleton = new Singleton01(); return singleton;
}
}

线程不安全。当多个线程同一时候调用getInstance方法时。都检測到singleton为null,然后就開始创建对象了,这时候就会创建多个实例,而不是一个。

public class Singleton02 {

	private static Singleton02 singleton = null;

	private Singleton02(){}

	public synchronized static Singleton02 getInstance(){

		if(singleton == null)
singleton = new Singleton02(); return singleton;
}
}

这个样例线程安全了,多个线程同一时候调用的时候也不会创建多个对象实例了。可是不是非常高效,须要多个线程依次的去运行这种方法。

public class Singleton03 {

	private static Singleton03 singleton = null;

	private Singleton03(){}

	public static Singleton03 getInstance(){

		if(singleton == null)
synchronized (Singleton03.class) { if(singleton == null){
singleton = new Singleton03();
}
} return singleton;
}
}

这样的方式被称为Double Check(双重检验),比較经典的设计。为什么要两次呢?先说外面的推断是避免对象已经创建好了之后,就不用再去同步运行创建对象去了,第二个是。防止第一次还没有创建实例的时候,多个线程已经在等待中,这个时候须要进行空的推断。防止后面等待的现场进入之后再次创建实例。

參考了其它人的文章【1】:

singleton = new Singleton()不是原子操作,在JVM中大致做了三件事情:

1. 给instance分配内存。

2. 通过其构造函数初始化成员变量。

3. 将instance指向分配的内存空间。

(运行完instance就不是null了)。

可是在JVM编译器中存在指令又一次排序的优化,终于的运行顺序是1-2-3或者1-3-2。假设是1-3-2的话。那么在3运行完成,2运行之前,线程A被线程B抢断的话,instance非空,线程B会直接返回instance,这个时候。直接使用就会报错。

给出的解决方案(使用volatilekeyword屏蔽重排序)是:

public class Singleton03 {

	private volatile static Singleton03 singleton = null;

	private Singleton03(){}

	public static Singleton03 getInstance(){

		if(singleton == null)
synchronized (Singleton03.class) { if(singleton == null){
singleton = new Singleton03();
}
} return singleton;
}
}

饿汉式



public class Singleton04 {

	private static final Singleton04 singleton = new Singleton04();

	private Singleton04(){
} public static Singleton04 getInstance(){
return singleton;
}
}

这样的方式是线程安全的,只是不足的一点是,即使没有调用getInstance方法。也会产生他的实例。之前的懒汉式的方式是懒载入的思想,在须要的时候创建。

静态内部类

public class Singleton05 {

	private static class Singleton{
private static final Singleton05 instance = new Singleton05();
} private Singleton05(){
} public Singleton05 getInstance(){
return Singleton.instance;
}
}

採用了静态内部类的方式,私有的静态内部类,外部无法訪问。类似于饿汉式的形式,可是在此基础上进行了改进,饿汉式是使用的内部属性,而这个是使用的静态内部类的常量。



枚举

神一样的设计,使用枚举实现单例模式的几个原因:

1. 自由序列化

2. 线程安全

3. 保证仅仅有一个实例。

public enum Singleton06 {

	INSTANCE;

	private Singleton06(){
} public void print(){
System.out.println("Enum Singleton!");
}
}

调用:



Singleton06.INSTANCE.print();

代码下载

下载代码

參考

【1】 http://wuchong.me/blog/2014/08/28/how-to-correctly-write-singleton-pattern/



&quot;围观&quot;设计模式(7)--创建型之单例模式(Singleton Pattern)的更多相关文章

  1. 设计模式01 创建型模式 - 单例模式(Singleton Pattern)

    参考 [1] 设计模式之:创建型设计模式(6种) | 博客园 [2] 单例模式的八种写法比较 | 博客园 单例模式(Singleton  Pattern) 确保一个类有且仅有一个实例,并且为客户提供一 ...

  2. 六个创建模式之单例模式(Singleton Pattern)

    定义: 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.三个特点:一个类只有一个实例:必需自己创建这个实例:必需自行向整个系统提供这个实例. 结构图: Singleton:单例类,提 ...

  3. 设计模式系列之单例模式(Singleton Pattern)

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式.这种模式涉及到一个单一的类,该类负责创建自己的对象 ...

  4. 设计模式系列之单例模式(Singleton Pattern)——确保对象的唯一性

    模式概述 模式定义 模式结构图 饿汉式单例与懒汉式单例 饿汉式单例 懒汉式单例 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 主要优点 适用场景 说明:设计模式系列文章是读刘伟所著 ...

  5. 浅谈设计模式--单例模式(Singleton Pattern)

    题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...

  6. 【设计模式】单例模式 Singleton Pattern

    通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance)  的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...

  7. 设计模式之单例模式(Singleton Pattern)

    单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...

  8. 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)

    原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ...

  9. Java设计模式之创建型模式

    创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类

随机推荐

  1. 阿里云ECS linux通过rinetd 端口转发来访问内网服务

    一.场景说明: 可以通过端口映射的方式,来通过具有公网的云服务器 ECS 访问用户名下其它未购买公网带宽的内网 ECS 上的服务.端口映射的方案有很多,比如 Linux 下的 SSH Tunnel.r ...

  2. Selenium webdriver Java 查找元素

    1.简单查找 By ID: WebElement element=driver.findElement(By.id("userId")); By Name:WebElement e ...

  3. 火车票抢票API 根据乘客的车次与座席要求快速订票出票

    火车票抢票API 根据乘客的车次与座席要求快速订票出票:https://www.juhe.cn/docs/api/id/257 1.站站查询 接口地址:http://v.juhe.cn/grabTic ...

  4. VLOOKUP多条件查找不使用辅助列

    问题描述: 可能很多人在使用VLOOKUP的时候,对于多条件时,则会使用辅助列进行查找,那么不使用辅助列是否也可以呢? 答案是:必须可以. 问题处理: 1.使用辅助列 2.不使用辅助列的操作如下: 公 ...

  5. Visual studio C++ MFC之Menu editor

    背景 本篇旨在MSDN帮助文档下总结Menu editor的使用,并列出碰到的具体问题. 正文 创建Menu Editor 打开链接MSDN之Creating a Menu.按照文档的方法创建Menu ...

  6. jquery遍历数组的方式

    1,for循环: var arr = new Array(13.5,3,4,5,6); for(var i=0;i<arr.length;i++){ arr[i] = arr[i]/2.0; } ...

  7. asp.net+mvc+easyui+sqlite 简单用户系统学习之旅(一)—— 手把手教你创建第一个三层架构+mvc的asp.net项目

    下面开启项目 1. 打开vs2010-文件-新建项目 2. 先创建一个空的解决方案: 选择其他项目类型-visual studio 解决方案-空白解决方案(默认.NET Framework 4),项目 ...

  8. dedecms上传图片相对路径改成绝对路径方法

    很多朋友使用dedecms的时候都用了二级域名的功能,所以造成很多文章中图片不显示的问题. 解决方案如下: 1. 进入dede后台"系统"-"系统基本参数"-& ...

  9. chrome 非安全模式解决开发跨域问题

    这个参数可以降低chrome浏览器的安全性,禁用同源策略,利于开发人员本地调试. ps:如果是mac用户(记得 Command + Q 关闭chrome):  open -a Google\ Chro ...

  10. 知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31无涯 - I

    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerExceptionv2 q31 1. #--现象 java.lang. ...