设计模式学习4——单例模式
来源:互联网 发布:燕十八mysql教程视频 编辑:程序博客网 时间:2024/05/17 22:24
参看:http://blog.csdn.net/lovelion/article/details/7420889
一、模式描述
单例模式(Singletion Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。
结构图:
角色:
Singleton(单例):在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例。
各种单例模式的实现:
单例模式必须保证实例在系统中的唯一性,防止创建多个对象,是单例模式的一个重要目标。为了防止创建多个对象,出现了不同的实现方法。
<1>、饿汉式单例
饿汉式单例在类加载时就创建单例对象,因此后续的使用就不可能创建多个对象。代码如下:
class EagerSingleton { private static final EagerSingleton instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return instance; } }
<2>懒汉式单例与双重检查锁定(Double-Check Locking)
懒汉式单例在第一次调用getInstance()方法时实例化,同时对getInstance()方法进行同步控制,从而保证对象的唯一性。
例如:直接用synchronized关键字修饰getinstance()方法,代码如下:
class LazySingleton { private static LazySingleton instance = null; private LazySingleton() { } synchronized public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }
上述代码的问题是每次调用getInstance()方法时都要进行线程锁定判断,在多线程高并发访问环境中,将会导致系统性能大大降低。
使用双重检查锁定(Double-Check Locking)来改进懒汉式单例,如下:
class LazySingleton { private volatile static LazySingleton instance = null; private LazySingleton() { } public static LazySingleton getInstance() { //第一重判断 if (instance == null) { //锁定代码块 synchronized (LazySingleton.class) { //第二重判断 if (instance == null) { instance = new LazySingleton(); //创建单例实例 } } } return instance; } }
注意:静态成员变量instance之前增加修饰符volatile。
<3>、饿汉式与懒汉式的比较
饿汉式单例类在类被加载时就将自己实例化,它的优点是无须考虑多线程访问问题,系统加载时需要创建对象,加载时间可能会比较长。
懒汉式单例类在第一次使用是创建,实现了延迟加载。需要多线程机制控制同步,影响系统运行性能。
<4>IoDH单例实现——最好的Java语言单例模式
通过 Initialization Demand Holder(IoDH)技术,实现延迟加载并且减少同步控制的单例类,(在单例类中增加一个静态内部类,在该内部类中创建单例对象,再将单例对象通过getInstance()方法返回给外部使用)代码如下:
//Initialization on Demand Holder class Singleton { private Singleton() { } private static class HolderClass { private final static Singleton instance = new Singleton(); } public static Singleton getInstance() { return HolderClass.instance; } public static void main(String args[]) { Singleton s1, s2; s1 = Singleton.getInstance(); s2 = Singleton.getInstance(); System.out.println(s1==s2); } }通过使用IoDH,可以实现延迟加载(因为Singleton类加载时不会加载静态内部类,而是当第一次调用getInstance()时将加载内部类HolderClass,此时会实例化Singleton),又可以保证线程安全(因为仅在静态内部类加载时初始化一次,由Java虚拟机来保证其线程安全性),不影响系统性能,是最好的Java语言单例模式实现方式。
二、模式优缺点
主要优点:
<1>、单例模式提供了对唯一实例的受控访问。
<2>、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。
<3>、允许可变数目的实例。基于单例模式我们可以扩展,使用与单例控制相似的方法来获得指定个数的对象实例。
主要缺点:
<1>、由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
<2>、单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身功能融合在一起。
<3>、现代面向对象语言提供了自动垃圾回收技术,如果实例化的共享对象长时间不被利用,系统会认为是来及,会自动销毁并回收资源,下次利用时又将重新实例化,导致共享的单例对象状态的丢失。
”
三、适用场景
<1>、系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
<2>、客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。
四、案例分析
- 设计模式学习4——单例模式
- 设计模式学习4 -- 单例模式
- 设计思想学习—单例模式
- 设计模式—单例设计模式
- 设计模式——单例模式(学习笔记)
- 设计模式学习笔记——单例模式
- 学习设计模式——单例模式
- JAVA设计模式学习7——单例模式
- 学习设计模式之禅——单例模式
- 设计模式学习(五)——单例模式
- 设计模式学习之——单例模式
- 设计模式学习笔记——单例模式
- 设计模式学习004——单例模式Singlton
- 学习设计模式——单例模式
- 单例模式——设计模式个人学习
- 设计模式学习——单例模式
- 设计模式学习笔记——单例模式
- 设计模式学习笔记——单例模式
- CSS3首页
- MultiImageSelector设置头像调用
- js的动画效果(封装运动框架)
- php 依赖注入
- 鸟人的Android揭秘(2)——通过启动过程分析 Android Framework
- 设计模式学习4——单例模式
- python多进程并发之multiprocessing
- win32不规则窗口详解
- 基于JXL和POI实现的读写Excel工具类(支持.xls和.xlsx格式)
- 如何自定义虚线背景框
- hbase HA模式安装
- jquery实现带搜索历史的搜索框
- 关于ListView中继承BaseAdapter重写getview的显示重复数据或报转换错误的问题
- OnTrimMemory优化