几乎所有面向对象的程序中,总有一些类的对象需要是唯一的,例如,通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销。再如大家最经常用的IM,如QQ,在同一台电脑,一个帐号只能有唯一的登录。

1. 问题

怎样确保一个特殊类的实例是独一无二的(它是这个类的唯一实例),并且这个实例易于被访问呢?

2. 解决方案

1)全局变量:一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象。因为你的任何代码都能修改全局变量,这将不可避免的引起更多调试的意外。换句话说,全局变量的状态总是会出现一些问题的。

2)类构造函数私有和类自身的静态方法:让类自身负责保存它的唯一实例(静态变量)。这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求) ,并且它可以提供一个访问该实例的方法(静态方法)。这就是Singleton模式。

3. 适用性
在下面的情况下可以使用单件模式
1)当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

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

4. 实现:

单例模式的五种写法:
 1、懒汉
 2、恶汉
 3、静态内部类
 4、枚举
 5、双重校验锁
一、懒汉,常用的写法
class LazySingleton{
    private static LazySingleton singleton;
    private LazySingleton(){
    }
    public static LazySingleton getInstance(){
        if(singleton==null){
            singleton=new LazySingleton();
        }
        return singleton;
    }  
}
二、恶汉,缺点:没有达到lazy loading的效果
class HungrySingleton{
    private static HungrySingleton singleton=new HungrySingleton();
    private HungrySingleton(){}
    public static HungrySingleton getInstance(){
        return singleton;
    }
}
三、静态内部类 优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading
class InternalSingleton{
    private static class SingletonHolder{
        private final static  InternalSingleton INSTANCE=new InternalSingleton();
    }  
    private InternalSingleton(){}
    public static InternalSingleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}
四、枚举,《Effective Java》作者推荐使用的方法,优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
enum EnumSingleton{
    INSTANCE;
    public void doSomeThing(){
    }
}
五、 双重校验锁,在当前的内存模型中无效
class LockSingleton{
    private volatile static LockSingleton singleton;
    private LockSingleton(){}
    //详见:http://www.ibm.com/developerworks/cn/java/j-dcl.html
    public static LockSingleton getInstance(){
        if(singleton==null){
            synchronized(LockSingleton.class){
                if(singleton==null){
                    singleton=new LockSingleton();
                }
            }
        }
        return singleton;
    }
}
 

设计模式(二)单例模式Singleton(创建型)的更多相关文章

  1. Java设计模式03:常用设计模式之单例模式(创建型模式)

    1.  Java之单例模式(Singleton Pattern ) 单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实 ...

  2. 设计模式01: Singleton 单例模式(创建型模式)

    Singleton 单例模式(创建型模式) 动机(Motivation)当进行软件开发是会有这样一种需求:在系统中只有存在一个实例才能确保它们的逻辑正确性.以及良好的效率.这应该是类设计者的责任,而不 ...

  3. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

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

    设计模式(4)  -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...

  5. 设计模式 笔记 单例模式 Singleton

    //---------------------------15/04/09---------------------------- //Singleton 单例模式-----对象创建型模式 /* 1: ...

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

    [设计模式]单例模式-SingletonEnsure a class has only one instance, and provide a global point to access of it ...

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

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

  8. 设计模式学习之单例模式(Singleton,创建型模式)(4)

    假如程序中有一个Person类,我的需求就是需要在整个应用程序中只能new一个Person,而且这个Person实例在应用程序中进行共享,那么我们该如何实现呢? 第一步: 新建一个Person类,类中 ...

  9. Java设计模式 - 单例模式(创建型模式)

    单例模式我在上学期看一些资料时候学习过,没想到这学期的软件体系结构就有设计模式学习,不过看似篇幅不大,介绍得比较简单,在这里我总结下单例模式,一来整理之前的笔记,二来也算是预习复习课程了. 概述 单例 ...

  10. Java设计模式——单例模式(创建型模式)

    概述   单例模式保证对于每一个类加载器,一个类仅有一个实例并且提供全局的访问.其是一种对象创建型模式.对于单例模式主要适用以下几个场景: 系统只需要一个实例对象,如提供一个唯一的序列号生成器 客户调 ...

随机推荐

  1. WINHTTP的API接口说明

    BOOL WINAPI WinHttpAddRequestHeaders(   _In_  HINTERNET hRequest,   _In_  LPCWSTR pwszHeaders,   _In ...

  2. 日志分析工具-ApexSQL介绍

    原文:日志分析工具-ApexSQL介绍 使用场景:业务数据异常变化,通过代码分析不出来的时候,迫不得已需要通过日志来分析 下载地址:http://www.apexsql.com/Download.as ...

  3. 【PLSQL】过程procedure形参和参数

    ************************************************************************   ****原文:blog.csdn.net/clar ...

  4. Android在包名称更改项目

    通常时引起包名称的变化R文件错误,有时原因不明Manifest混乱多个文本文件. 所以,我们现在感到最简单方便的包名称变更流程文件,如以下: 如果程序包命名com.pepper.util,我们将更改包 ...

  5. 64位平台支持大于2 GB大小的数组

    64位平台支持大于2 GB大小的数组 64位平台.NET Framework数组限制不能超过2GB大小.这种限制对于需要使用到大型矩阵和向量计算的工作人员来说,是一个非常大问题. 无论RAM容量有多大 ...

  6. [问题]安装express,已经加了-g,还是找不到express命令

    安装express时使用如下命令: npm install -g express 但是在命令行还是找不到express 手动将路径D:\Program Files (x86)\nodejs\node_ ...

  7. 带你走近AngularJS 之创建自定义指令

    带你走近AngularJS 之创建自定义指令 为什么使用AngularJS 指令? 使用过 AngularJS 的朋友应该最感兴趣的是它的指令.现今市场上的前端框架也只有AngularJS 拥有自定义 ...

  8. Bootstrap 模态框

    Bootstrap 模态框(也可以说的弹出层) 最近在尝试使用bootstrap的模态框 使用模态框主要要引入一下几个js和css: bootstrap.css jquery.1.9.1.js(这个可 ...

  9. ArcGIS 10.1 发布使用ArcEngine自定义的GP服务

    1. 新建立GP模型 在VS2010中新建一个普通的程序及,引入ArcEngine相关的dll.在该DLL中定义一个或多个GP类和一个GP工厂类.GP类要继承IGPFunction2接口,GP工厂类要 ...

  10. Stub和Mock的理解

    我对Stub和Mock的理解 介绍 使用测试驱动开发大半年了,我还是对Stub和Mock的认识比较模糊,没有进行系统整理. 今天查阅了相关资料,觉得写得很不错,所以我试图在博文中对资料进行整理一下,再 ...