前言:继续学习设计模式。单例模式的类图好像是最简单的呢。转载请注明出处:http://www.cnblogs.com/yuxiaole/p/9310345.html

单例模式(Singleton pattern)

定义:确保一个类只有一个示例,并提供一个全局访问点。

类图:

使用场景:有一些对象其实我们只需要一个。比如:线程池、缓存、日志对象等,这些对象如果有多个,会导致许多问题产生。

总结:

  1、单例模式给了我们一个全局的访问点,和全局变量一样方便,又没有全局变量的缺点。因为单例模式使用了延迟示例化的方式创建对象。

(全局变量的缺点:如果将对象赋值给一个全局变量,那么我们必须在程序一开始就创建好对象,但是万一这个对象很耗费资源,而且程序在这次的执行过程中又一直没有用到它,这就会形成浪费。而且全局变量也不能保证只有一个实例)。

  2、没有公开的构造器。构造器是私有的。

  3、现在的java版本,垃圾收集器不会回收单例模式创建的对象。

  4、如果程序有两个类加载器,同时又使用了单例模式,这种情况下不同的类加载器可能都会去加载这个单例类。解决方法:自行指定类加载器,并指定同一个类加载器。

demo:

  1、如果是单线程,代码可以如下:

/*** 单线程中的单例实现* Created by yule on 2018/7/14 17:04.*/
public class Singleton1 {private static Singleton1 uniqueInstance;private Singleton1(){}public static Singleton1 getInstance(){if(uniqueInstance == null){uniqueInstance = new Singleton1();}return uniqueInstance;}
}

  这种的缺点是不适用与多线程中。 

  2、同步 getInstance() 方法:如果是多线程中,不关心性能问题,这是最简单有效的方式,则代码可以如下(加了synchronized):

public class Singleton2 {private static Singleton2 uniqueInstance;private Singleton2(){}public static synchronized Singleton2 getInstance(){if(uniqueInstance == null){uniqueInstance = new Singleton2();}return uniqueInstance;}
}

  这种的缺点在于:同步的 getInstance() 的做法会拖垮性能,可能使执行效率下降100倍。毕竟只有第一次执行此方法时,才真正需要同步。换句话说,一旦设置好 uniqueInstance 变量,就不再需要同步这个方法了。之后每次调用这个方法,同步都是一种累赘

  3、急切实例化(饿汉模式):保证了线程安全,如果应用程序总是创建并使用单例实例,或者在创建和运行时方面的负担不太繁重,可以采用下面这种方式:

public class Singleton3 {private static Singleton3 uniqueInstance = new Singleton3();private Singleton3(){}public static Singleton3 getInstance(){return uniqueInstance;}
}

  这种方式是在静态初始化器(static initializer)中创建单例。这也是保证了线程安全。利用这个做法,我们依赖 JVM 在加载这个类时马上创建此唯一的单例实例。JVM 保证在任何线程访问 uniqueInstance 静态变量之前,一定先创建此实例。

  这种方式的缺点在于:初始化时如果很耗费资源,而且程序在这次的执行过程中又一直没有用到它,这就会形成浪费。

  4、双重检查加锁:如果性能是关心的重点,则这种方式可以减少时间的耗费,减少 getInstance() 中使用同步的方式(注意加 volatile):

public class Singleton4 {private volatile static Singleton4 uniqueInstance = null;private Singleton4(){}public static Singleton4 getInstance(){if(uniqueInstance == null){synchronized (Singleton4.class){if(uniqueInstance == null){uniqueInstance = new Singleton4();}}}return uniqueInstance;}
}

  这种方式,进入同步区块只会在第一次才进入。

  这里的 singleton 使用double check locking是需要加volatile的(前提是jdk1.5之后);

  如果不加volatile,虽然里面加了锁,能保证这个同步块至多只有一个线程运行,但是不能保证有序性,即在此句中: instance = new Singleton(); 这不是一个原子操作,所以构造方法是有可能没有执行完,instance就拿到了这个值,从而出现问题。也就是说:这一块代码,有线程A和线程B,如果A先进入第一个if语句,A线程开始实例化Singleton对象,对象的实例化有三个步骤: 分配内存空间,初始化对象,将内存中的地址赋值给变量。这里可能会发生重排序,如果这里先执行分配和赋值操作,线程B此时进入第一个if语句,发现变量不为null,直接返回这个实例,然后B线程此时拿到的可能是还没有实例化的对象。 所以用volatile修饰singleton就可以避免这种重排序了。 注意:volatile不能保证操作的原子性。

  在getInstance上加同步,不需要考虑这个,是由于 synchronized 能够保证任一时刻只有一个线程执行该代码块,那么自然就不存在原子性问题了,从而保证了原子性。

  至于为何需要这么写请参考:Java并发编程:volatile关键字解析、《Java 中的双重检查(Double-Check)》http://blog.csdn.net/dl88250/article/details/5439024 和 http://www.iteye.com/topic/652440

转载请注明出处:http://www.cnblogs.com/yuxiaole/p/9310345.html

转载于:https://www.cnblogs.com/yuxiaole/p/9310345.html

初识设计模式(单例模式)相关推荐

  1. 初识设计模式、软件设计的六大原则

    总结:本篇文字分为两个部分.第一部分:设计模式基本常识:第二部分:软件设计中的六大原则,并详细分析了单一职责原则.(本篇文章的时间轴参考:为知笔记支撑文件夹\Java设计模式(时间序列图).vsdx) ...

  2. Python设计模式-单例模式

    Python设计模式-单例模式 基于Python3.5.2,代码如下 #coding:utf-8 import threading import timeclass Singleton(object) ...

  3. Android设计模式——单例模式(Singleton)

    二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元 ...

  4. 【学习笔记】ABAP OOD设计模式 - 单例模式

    ABAP OOD设计模式 - 单例模式 整理转自-<SAP ABAP 面向对象程序设计(原则.模式及实践)> 单例模式(Singleton Pattern)是常用的且较为简单的软件设计模式 ...

  5. Go 语言实现 23 种设计模式 单例模式

    Go 语言实现 23 种设计模式 单例模式 单例模式 单例模式是一种常用的软件设计模式,在使用过程中,单例对象的类只有一个实例.使用单例模式,1 可以节省内存等资源,例如windows操作系统的资源管 ...

  6. java singleton inner class_Java面向对象设计模式-单例模式

    Java面向对象设计模式-单例模式 2020-05-28 589 0 单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点,有多重实现方式. 一.饿汉式单例模式,构造方法私有化,在加载类Sin ...

  7. Java开发中常用的设计模式-单例模式

    单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式. Java开发中常用的设计模式-单例模式 单例模式有3个特点: 单例类只有一个实例对象: 该单例对象必须 ...

  8. 炒冷饭系列:设计模式 单例模式

    2019独角兽企业重金招聘Python工程师标准>>> 炒冷饭系列:设计模式 单例模式 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆 ...

  9. 设计模式-单例模式-注册式单例模式-枚举式单例模式和容器式单例模式在Java中的使用示例

    场景 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例: 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例_霸道流氓气质的博客- ...

  10. 设计模式----创建型设计模式(单例模式、工厂方法模式、构建者模式)

    创建型设计模式 单例模式(Singleton Pattern) 单例模式介绍 代码演示 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全, ...

最新文章

  1. Android Studio Day03-2(常用操作)
  2. Redis中字符串string数据类型(保存(设置键值、过期时间、设置多个键值、追加值)、获取(获取单一键值、获取多个键值))
  3. SQL SERVER特殊行转列案列一则
  4. 【c语言】蓝桥杯算法提高 统计平均成绩
  5. 反模式? 只有模式不彻底吧
  6. CALL TRANSACTION 小节
  7. 在栈中压入一个字符串c语言,面试题 31:栈的压入、弹出序列
  8. 练习利用LSTM实现手写数字分类任务
  9. 关于计算机书籍的收集与整理(一)
  10. php 高德地图计算距离,距离、长度、面积
  11. 基于shiro实现session持久化和分布式共享
  12. 使用java如何访问报表服务器_Java访问远程http服务器上数据的简便方法
  13. linux arm fpu初始化,ARM处理器的浮点运算单元(FPU)
  14. 对超级计算机的认识有关论文,计算机科与技术专业的认识与思考.docx
  15. 拓端tecdat|R语言乘法GARCH模型对高频交易数据进行波动性预测
  16. Activiti 6.0 概述与 Hello World 快速入门 与 核心 API 概述
  17. 2019年全国一二线城市程序员工资大调查
  18. IOS收起键盘的几种办法(摘抄自唐巧《iOS开发进阶》)
  19. ORACLE应用产品和SAP、SSA、SYMIX产品的比较分析
  20. 《炬丰科技-半导体工艺》多层薄膜封装工艺

热门文章

  1. Python的函数式编程--从入门到⎡放弃⎦
  2. Android checkCallingPermission()方法返回值问题
  3. (20120731)Android中的各种对话框总结(dialog)
  4. 【转载】面向对象建模与数据库建模两种分析设计方法的比较
  5. 一个新基民的感叹:人心不足蛇吞象
  6. 文件服务器的未分页内存
  7. UTC转换BJT时间 时间转换 c语言程序设计 mooc 翁恺
  8. 订单生产计划表范本_服装生产管理必看丨一文解决车间管理混乱
  9. ModuleNotFoundError: No module named ‘keras.api‘
  10. 用每日新闻预测金融市场变化