`
liss
  • 浏览: 842346 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

深入浅出单实例Singleton设计模式

阅读更多

单实例Singleton设计模式可能是被讨论和使用的最广泛的一个设计模式了,这可能也是面试中问得最多的一个设计模式了。这个设计模式主要目的是想在整个系统中只能出现一个类的实例。这样做当然是有必然的,比如你的软件的全局配置信息,或者是一个Factory,或是一个主控类,等等。你希望这个类在整个系统中只能出现一个实例。当然,作为一个技术负责人的你,你当然有权利通过使用非技术的手段来达到你的目的。比如:你在团队内部明文规定,“XX类只能有一个全局实例,如果某人使用两次以上,那么该人将被处于2000元的罚款!”(呵呵),你当然有权这么做。但是如果你的设计的是东西是一个类库,或是一个需要提供给用户使用的API,恐怕你的这项规定将会失效。因为,你无权要求别人会那么做。所以,这就是为什么,我们希望通过使用技术的手段来达成这样一个目的的原因。

本文会带着你深入整个Singleton的世界,当然,我会放弃使用C++语言而改用Java语言,因为使用Java这个语言可能更容易让我说明一些事情。


Singleton的教学版本
这里,我将直接给出一个Singleton的简单实现,因为我相信你已经有这方面的一些基础了。我们姑且把这具版本叫做1.0版

// version 1.0
public class Singleton
{
private static final Singleton singleton = null;

private Singleton()
{
}
public static Singleton getInstance()
{
if (singleton== null)
{
singleton= new Singleton();
}
return singleton;
}
}
在上面的实例中,我想说明下面几个Singleton的特点:(下面这些东西可能是尽人皆知的,没有什么新鲜的)

私有(private)的构造函数,表明这个类是不可能形成实例了。这主要是怕这个类会有多个实例。
即然这个类是不可能形成实例,那么,我们需要一个静态的方式让其形成实例:getInstance()。注意这个方法是在new自己,因为其可以访问私有的构造函数,所以他是可以保证实例被创建出来的。
在getInstance()中,先做判断是否已形成实例,如果已形成则直接返回,否则创建实例。
所形成的实例保存在自己类中的私有成员中。
我们取实例时,只需要使用Singleton.getInstance()就行了。
当然,如果你觉得知道了上面这些事情后就学成了,那我给你当头棒喝一下了,事情远远没有那么简单。

Singleton的实际版本
上面的这个程序存在比较严重的问题,因为是全局性的实例,所以,在多线程情况下,所有的全局共享的东西都会变得非常的危险,这个也一样,在多线程情况下,如果多个线程同时调用getInstance()的话,那么,可能会有多个进程同时通过 (singleton== null)的条件检查,于是,多个实例就创建出来,并且很可能造成内存泄露问题。嗯,熟悉多线程的你一定会说——“我们需要线程互斥或同步”,没错,我们需要这个事情,于是我们的Singleton升级成1.1版,如下所示:

// version 1.1
public class Singleton
{
private static final Singleton singleton = null;

private Singleton()
{
}
public static Singleton getInstance(){
if (singleton== null)
{
synchronized (Singleton.class) {
singleton= new Singleton();
}
}
return singleton;
}
}
嗯,使用了Java的synchronized方法,看起来不错哦。应该没有问题了吧?!错!这还是有问题!为什么呢?前面已经说过,如果有多个线程同时通过(singleton== null)的条件检查(因为他们并行运行),虽然我们的synchronized方法会帮助我们同步所有的线程,让我们并行线程变成串行的一个一个去new,那不还是一样的吗?同样会出现很多实例。嗯,确实如此!看来,还得把那个判断(singleton== null)条件也同步起来。于是,我们的Singleton再次升级成1.2版本,如下所示:


// version 1.2
public class Singleton
{
private static final Singleton singleton = null;

private Singleton()
{
}
public static Singleton getInstance()
{
synchronized (Singleton.class)
{
if (singleton== null)
{
singleton= new Singleton();
}
}
return singleton;
}
}
不错不错,看似很不错了。在多线程下应该没有什么问题了,不是吗?的确是这样的,1.2版的Singleton在多线程下的确没有问题了,因为我们同步了所有的线程。只不过嘛……,什么?!还不行?!是的,还是有点小问题,我们本来只是想让new这个操作并行就可以了,现在,只要是进入getInstance()的线程都得同步啊,注意,创建对象的动作只有一次,后面的动作全是读取那个成员变量,这些读取的动作不需要线程同步啊。这样的作法感觉非常极端啊,为了一个初始化的创建动作,居然让我们达上了所有的读操作,严重影响后续的性能啊!

还得改!嗯,看来,在线程同步前还得加一个(singleton== null)的条件判断,如果对象已经创建了,那么就不需要线程的同步了。OK,下面是1.3版的Singleton。
// version 1.3
public class Singleton
{
private static final Singleton singleton = null;

private Singleton()
{
}
public static Singleton getInstance()
{
if (singleton== null)
{
synchronized (Singleton.class)
{
if (singleton== null)
{
singleton= new Singleton();
}
}
}
return singleton;
}
}
感觉代码开始变得有点罗嗦和复杂了,不过,这可能是最不错的一个版本了,这个版本又叫“双重检查”Double-Check。下面是说明:

第一个条件是说,如果实例创建了,那就不需要同步了,直接返回就好了。
不然,我们就开始同步线程。
第二个条件是说,如果被同步的线程中,有一个线程创建了对象,那么别的线程就不用再创建了。

分享到:
评论

相关推荐

    深入浅出单例Singleton模式

    【深入浅出单例Singleton模式】 单例模式是一种在软件设计中常见的设计模式,它的核心目标是确保一个类只有一个实例,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于控制资源的共享,如全局...

    深入浅出设计模式附书源码Java版源码

    深入浅出设计模式附书源码Java版源代码,是面向Java开发者的宝贵资源,旨在帮助他们理解和实践各种设计模式。这本书籍的源代码提供了实际的示例,使得学习过程更具互动性和实践性。 设计模式的核心思想是将常见的...

    深入浅出设计模式之单件模式

    ### 深入浅出设计模式之单件模式 #### 一、单件模式概述 单件模式(Singleton Pattern)是软件设计模式中最为常见的一种,它的主要目标是确保某个类只有一个实例,并提供一个全局访问点。单件模式在很多情况下都...

    深入浅出设计模式.rar

    《深入浅出设计模式》这个压缩包文件很可能是为了帮助读者理解和掌握设计模式的核心理念与应用场景,从而提升软件开发的效率和质量。 在软件开发过程中,设计模式如同一种通用的语言,让开发者能够快速交流复杂的...

    深入浅出设计模式.pdf

    《深入浅出设计模式》是一本关于软件设计的经典著作,主要涵盖了面向对象设计中的核心设计模式。这本书旨在帮助读者理解并掌握如何在实际编程中应用这些模式,提升代码的可维护性和可扩展性。设计模式是经过时间和...

    深入浅出设计模式 C++ 源码 + 设计模式 C++

    本资料包包含“深入浅出设计模式 C++”的源码和相关教材,旨在帮助开发者理解和应用设计模式。 一、设计模式的重要性 设计模式不仅提供了可重用的代码结构,还促进了团队间的沟通和代码的可维护性。它们是经验丰富...

    深入浅出设计模式 (希望对设计模式有所了解和深入研究的都适用)

    《深入浅出设计模式》是一本旨在帮助读者理解和掌握设计模式的书籍,适合那些希望深入研究设计模式的IT从业者。这本书可能与《HEAD FIRST设计模式》相辅相成,通过不同的讲解方式来帮助读者更全面地理解这一领域。 ...

    深入浅出Java 23种设计模式.rar

    本资料"深入浅出Java 23种设计模式"旨在帮助开发者理解和应用这23种经典设计模式。 首先,我们要了解设计模式的三大类别:创建型模式、结构型模式和行为型模式。创建型模式关注对象的创建过程,如单例模式...

    深入浅出的设计模式 ptf

    本书通过深入浅出的方式,将复杂的理论转化为易于理解的实例,为初学者提供了进入设计模式殿堂的路径。 首先,我们要明白什么是设计模式。设计模式不是具体的代码或库,而是一种描述在特定情况下如何设计软件的通用...

    深入浅出设计模式样章

    《深入浅出设计模式样章》是一本专为软件开发者准备的指南,旨在帮助读者理解和掌握设计模式这一核心编程概念。设计模式是软件工程中经过时间验证、在特定情境下解决常见问题的有效方法,它提供了可重用的解决方案,...

    Head.First深入浅出设计模式

    《Head.First深入浅出设计模式》书中首先介绍的是创建型设计模式,这些模式主要涉及对象的创建,旨在简化对象实例化过程,提高代码的灵活性和可扩展性。 1. **单例模式(Singleton)**:保证一个类只有一个实例,并...

    深入浅出设计模式之与设计模式相处

    根据提供的标题“深入浅出设计模式之与设计模式相处”以及描述“将《Head First 设计模式》(中文版)按章节进行了分割,每章一个文件,方便大家下载”,我们可以推测出这部分内容主要关注的是设计模式的基础理论及其...

    设计模式设计模式设计模式

    设计模式是软件工程中的一种重要概念,它是在特定情境下为解决常见问题而形成的一套最佳实践。在软件开发过程中,设计模式可以帮助我们构建可...因此,深入学习和掌握设计模式对于任何IT专业人士来说都是非常重要的。

    深入浅出设计模式源码 java

    《深入浅出设计模式源码 Java》是一本深入解析Java设计模式的著作,它通过易于理解的方式揭示了软件设计中的核心原则和模式。设计模式是软件工程中的宝贵经验总结,它们是解决常见问题的最佳实践,可以帮助开发者...

    HeadFirst设计模式(深入浅出设计模式)-高清

    《HeadFirst设计模式》是一本深受开发者喜爱的经典书籍,它以独特的方式深入浅出地讲解了设计模式这一重要编程概念。设计模式是软件工程中经过实践验证的、解决常见问题的有效解决方案,对于提升代码可读性、可维护...

    23种设计模式整理pdf

    设计模式详解 设计模式是软件开发中的一种解决方案,旨在提高代码的可重用性、可维护性和可扩展性。在这篇文章中,我们将对23种常见的设计模式进行整理和解释。 1. Singleton 模式 Singleton 模式是一种创建型模式...

    Head First Design Patterns 深入浅出设计模式

    总之,《Head First Design Patterns》是一本值得推荐的书籍,无论你是刚开始接触设计模式,还是想深入理解和应用设计模式,它都能提供宝贵的指导。通过学习这本书,你将能够更好地理解和应用设计模式,从而成为一名...

    关于java深入浅出设计模式

    本资料“关于java深入浅出设计模式”旨在帮助读者全面理解和掌握Java中的设计模式。 一、单例模式(Singleton) 单例模式确保一个类只有一个实例,并提供一个全局访问点。在Java中,通常通过私有构造器和静态工厂...

    深入浅出C#设计模式 HeadFirst Design Patterns 书籍代码例子

    《深入浅出C#设计模式》是面向C#开发者的一本经典书籍,它基于HeadFirst Design Patterns的理念,用易于理解的方式介绍了多种设计模式。设计模式是软件开发中的经验总结,是一套解决常见问题的最佳实践。这本书通过...

Global site tag (gtag.js) - Google Analytics