基本概括

详解

一、单例模式定义:

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

二、单例模式特点:

1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性。

三、线程安全的问题

一方面在获取单例的时候,要保证不能产生多个实例对象,后面会详细讲到五种实现方式;

另一方面,在使用单例对象的时候,要注意单例对象内的实例变量是会被多线程共享的,推荐使用无状态的对象,不会因为多个线程的交替调度而破坏自身状态导致线程安全问题,比如我们常用的VO,DTO等(局部变量是在用户栈中的,而且用户栈本身就是线程私有的内存区域,所以不存在线程安全问题)。

四、单例模式的侧重点

实现要点

l Singleton模式是限制而不是改进类的创建。

l Singleton类中的实例构造器可以设置为Protected以允许子类派生。

l Singleton模式一般不要支持Icloneable接口,因为这可能导致多个对象实例,与Singleton模式的初衷违背。

l Singleton模式一般不要支持序列化,这也有可能导致多个对象实例,这也与Singleton模式的初衷违背。

l Singleton只考虑了对象创建的管理,没有考虑到销毁的管理,就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。

l 理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的构造器的任意调用”。

l 可以很简单的修改一个Singleton,使它有少数几个实例,这样做是允许的而且是有意义的。

优点

l 实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例

l 灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程

缺点

l 开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题,上面的五种实现方式中已经说过了。

l 可能的开发混淆:使用 singleton 对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用 new 关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

l 对象的生存期:Singleton 不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于 .NET Framework 的语言),只有 Singleton 类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除

对象实例,但这样会导致 Singleton 类中出现悬浮引用。

适用性

l 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

l 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

应用场景

l 每台计算机可以有若干个打印机,但只能有一个Printer Spooler,避免两个打印作业同时输出到打印机。

l PC机中可能有几个串口,但只能有一个COM1口的实例。

l 系统中只能有一个窗口管理器。

l .NET Remoting中服务器激活对象中的Sigleton对象,确保所有的客户程序的请求都只有一个实例来处理。

五、实现单例模式的方式

1.饿汉式单例(立即加载方式)(加载时就已经初始化)

// 饿汉式单例

public class Singleton1 { // 私有构造 private Singleton1() {} private static Singleton1 single = new Singleton1(); // 静态工厂方法 public static Singleton1 getInstance() { return single; }}

饿汉式单例在类加载初始化时就创建好一个静态的对象供外部使用,除非系统重启,这个对象不会改变,所以本身就是线程安全的。

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论,姑且闭着眼就认为反射机制不存在。)

性能:性能不是很好,若长期不使用会占用内存空间,内存空间不足时容易造成内存溢出异常。

2.懒汉式单例(延迟加载方式)

// 懒汉式单例

public class Singleton2 { // 私有构造 private Singleton2() {} private static Singleton2 single = null; public static Singleton2 getInstance() { if(single == null){ single = new Singleton2(); } return single; }}

该示例虽然用延迟加载方式实现了懒汉式单例,但在多线程环境下会产生多个single对象,如何改造请看以下方式:

使用synchronized同步锁

public class Singleton3 {

// 私有构造

private Singleton3() {}

private static Singleton3 single = null;

public static Singleton3 getInstance() {

// 等同于 synchronized public static Singleton3 getInstance()

synchronized(Singleton3.class){

// 注意:里面的判断是一定要加的,否则出现线程安全问题

if(single == null){

single = new Singleton3();

}

}

return single;

}

}

在方法上加synchronized同步锁或是用同步代码块对类加同步锁,此种方式虽然解决了多个实例对象问题,但是该方式运行效率却很低下,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。

public class Singleton4 {

 // 私有构造 private Singleton4() {} private static Singleton4 single = null; // 双重检查 public static Singleton4 getInstance() { if (single == null) { synchronized (Singleton4.class) { if (single == null) { single = new Singleton4(); } } } return single; }}

使用双重检查进一步做了优化,可以避免整个方法被锁,只对需要锁的代码部分加锁,可以提高执行效率。

3.静态内部类实现

public class Singleton6 { // 私有构造 private Singleton6() {} // 静态内部类 private static class InnerObject{ private static Singleton6 single = new Singleton6(); }  public static Singleton6 getInstance() { return InnerObject.single; }}

静态内部类虽然保证了单例在多线程并发下的线程安全性,但是在遇到序列化对象时,默认的方式运行得到的结果就是多例的。

4.static静态代码块实现

// 私有构造

 private Singleton6() {}  private static Singleton6 single = null; // 静态代码块 static{ single = new Singleton6(); } public static Singleton6 getInstance() { return single; }}

问题

懒汉模式和饿汉模式的区别

懒汉模式:在类加载的时候不被初始化。

饿汉模式:在类加载时就完成了初始化,但是加载比较慢,获取对象比较快。

饿汉模式是线程安全的,在类创建好一个静态对象提供给系统使用,懒汉模式在创建对象时不加上synchronized,会导致对象的访问不是线程安全的

喜欢的可以点下关注。

was修改类加载模式_java基础——单例(Singleton)模式介绍相关推荐

  1. 设计模式学习笔记——单例(Singleton)模式

    设计模式学习笔记--单例(Singleton)模式 @(设计模式)[设计模式, 单例模式, Singleton, 懒汉式, 饿汉式] 设计模式学习笔记单例Singleton模式 基本介绍 单例案例 类 ...

  2. 设计模式--单例(Singleton)模式

    模式意图 保证一个类只用一个实例,并且提供一个全局访问点 类图 应用场景 1.需要更严格地控制全局变量时,使用单例模式: 2.重量级的对象如线程池对象,数据库连接池对象,不需要多个实例的对象如工具类等 ...

  3. 设计一个线程安全的单例(Singleton)模式

    在设计单例模式的时候.尽管非常easy设计出符合单例模式原则的类类型,可是考虑到垃圾回收机制以及线程安全性.须要我们思考的很多其它.有些设计尽管能够勉强满足项目要求,可是在进行多线程设计的时候.不考虑 ...

  4. 设计模式C++描述----01.单例(Singleton)模式

    一.概念 单例模式:其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享. class CSingleton { //公有的静态方法,来获取该实例 public: s ...

  5. 单例/单体模式(Singleton)

    单例/单体模式(Singleton) 首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点: 1,该类只有一个实例 2,该类自行创建该实例(在该类内部创建自身的实例对象) 3,向 ...

  6. 单例测试模式中【饿汉式】与【懒汉式】的区别

    package day25.thread;/** /*** @author Mr Chen* @create 2018-10-09 18:37* 单例测试模式:保证类在内存中只有一个对象*/ publ ...

  7. Ruby设计模式透析之 —— 单例(Singleton)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8868758 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

  8. 跨应用程序域(AppDomain)的单例(Singleton)实现

    转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...

  9. java 单例设计_Java 之单例设计模式

    设计模式: 对问题行之有效的解决方式, 其实它是一种思想. 单例设计模式 解决的问题:就是可以保证一个类在内存中的对象唯一性. 即单个实例. 比如对于A 和 B 两个程序使用同一个配置信息对象时, A ...

最新文章

  1. No entry found for dependency in Cartfile.
  2. 【深度学习入门到精通系列】Mean Iou
  3. html 属于mvvm框架,mvvm模式和mvc的区别是什么?
  4. .Net——使用DataContractJsonSerializer进行序列化及反序列化基本操作
  5. mysql查询含有某个值的表_MYSQL查询数据表中某个字段包含某个数值
  6. mysql索引原理传送门_MySQL索引底层实现原理
  7. 红橙Darren视频笔记 OKHttp基本使用 对http框架进行封装 链式调用
  8. [转载] python不允许使用关键字_Python中关键字global与nonlocal的区别
  9. WebRequest中的工厂方法模式
  10. 《深入理解mybatis原理》 MyBatis的架构设计以及实例分析
  11. android表格布局占满整行,Android布局之表格布局TableLayout详解
  12. arc 093 F Dark Horse
  13. 设计模式01---设计模式基础篇01
  14. 京东图书详情页定价获取
  15. Java io流 解压缩多个文件 损坏问题解决
  16. 计算机协会游园活动方案,大学计算机协会演讲比赛活动策划方案
  17. python编程练习:求最大公约数和最小公倍数
  18. gets()和getchar()的用法
  19. 【微信小程序】一文带你吃透小程序开发框架——视图层中的事件系统
  20. 标签体系-内容建设思路

热门文章

  1. Shell中的if判断
  2. SQL语言之数据控制语言(Oracle)
  3. core identity mysql_Asp.Net Core Identity 4 改成 MySql/MariaDB
  4. 广州的11个辖区_广州上半年经济发展情况,天河区总量超过2000亿
  5. C语言学生成绩简单,C语言实现简单学生成绩管理系统.pdf
  6. 【数据结构-树】2.二叉树遍历与线索二叉树(图解+代码)
  7. Java 中这些常用关键字,总有那么些被你遗忘的
  8. 数据结构与算法-排序与查找(java描述)
  9. 崔家桥计算机学校,汉寿县崔家桥中学
  10. python3模拟登陆人人网(requests)