`
Dapple
  • 浏览: 102092 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Singleton Pattern 单态模式

阅读更多
Singleton Pattern 单态模式。

这个模式较简单,就是为了保证一个类只有一个实例,用一个入口来获取该实例。

例子如下(代码来自维基):

class Foo {
    private static Helper helper = null;
    private Foo(){}
    public static Helper getHelper() {
        if (helper == null)
            helper = new Helper();
        return helper;
    }
 
    // other functions and members...
}

由于构造方法设为了私有,所以其它类无法使用new 来生成该类实例,只有通过
该类自己提供的方法来获取实例。这个获取实例的方法通总是使用第一次创建的
实例而保证其它类总是使用同一个实例。

本来很简单,但是在多线程情况下则会有些麻烦。两个线程都有可能执行到了第
6行,这样就有可能创建2个实例。过程如下(线程1简称为T1,线程2 简称T2):

T1 5 (5代表第5行)
T2 5
T1 6
T1 7 (线程1返回一个实例)
T2 6
T2 7 (线程2返回另一个实例)

这样就破坏了实例唯一性。如果这两个实例状态不会变化,倒也无所谓,就是多
花点内存养两个对象。但如果这两个实例涉及到计数器等状态变化,就埋下了隐患。

解决办法是加上同步关键字,如下:

    public static synchronized Helper getHelper() {
        if (helper == null)
            helper = new Helper();
        return helper;
    }


问题是解决了,但效率却降低了。因为每次获取实例都会执行同步运算。实际上
没必要。一旦实例创建并返回,以后再获取实例就不会执行第6行。为了发生几率
很小的事件而每次同步的方法,代价太大了。

不同虚拟机对同步方法的执行效率不同,早期虚拟机执行同步效率非常的低。现
在改进了很多,但进入线程体、离开线程体、加锁、解锁这些步骤仍然耗费性能。

所以,后来发明了双检查锁模式。(Double-Checked Locking Pattern)。在
《DesignPatternsExplained》一书中,作者专门分析了这种方法的优势,并给出
了代码。代码如下:

class USTax {
    private static USTax instance;
    private synchronized USTax(){};
    public static USTax getlnstance () {
if(instance== null)
     instance= new USTax(); 
return instance; 
    } 
}


不想,书上印错了,这让很多人包括我迷惑良久。后来书本经过更正,变为如下形式,

class USTax {
   private static USTax instance;
   private USTax(){};
   public static synchronized void doSyn(){
 if(instance== null){
     instance= new USTax();
     instance.setSomething();}//这句是我加的,为方便接下来的解释。
   }
   public static USTax getlnstance () {
 if(instance== null)
      doSyn();
 return instance; 
    } 
}


到此,算是万事大吉了。不料这种双重检查模式仍然有问题,并不能解决多线程
的问题。由于这本书的广泛流传,这种模式也广为人知。当这种模式的错误之处
被发现后,很快就出现了对这种模式广泛的讨伐之声。可见,影响越大,一旦有
错,被讨伐的力度也就越大。

我们以上面这段代码为例,看看问题是怎样产生的,

T1 10 (线程1执行到第10行)
T1 5
T1 6
T2 10
T2 12

也就是说,线程1还没有完全构造完这个对象(还没有执行第7行),线程2就返回
这个半成品对象了。所以,这种谬种流传的 Double-Checked Locking Pattern也
就寿终正寝,不能再被使用了。

那这种多线程出现的问题该怎么做呢,解决方法也很简单,如下即可,

class USTax {
   private static USTax instance = new USTax();
   private USTax(){};
   public static synchronized void doSyn(){
if(instance== null)
     instance= new USTax();
   }
   public static USTax getlnstance () {
return instance; 
    } 
}
0
2
分享到:
评论
1 楼 mercyblitz 2010-05-31  
貌似DLC还是有问题啊,在static字段那里需要加一个volatile.

相关推荐

    单态模式(代码)

    单态模式(Singleton Pattern)是软件设计模式中的一种,它保证了类只有一个实例,并提供一个全局访问点。这种模式在很多场景下非常有用,比如配置管理、线程池、缓存管理和日志记录等,因为它可以确保在整个系统中...

    Net单态模式的案例

    单态模式(Singleton Pattern)是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在.NET环境中,无论是C#还是ASP.NET项目,单态模式都是经常被用到的设计模式之一,尤其在处理全局配置、...

    .Net单态模式的案例

    单态模式(Singleton Pattern)是设计模式中的一种,它的核心思想是限制类的实例化,确保一个类只有一个实例,并提供全局访问点。在.NET开发中,单态模式被广泛应用于那些需要频繁实例化然后销毁的对象,或者需要...

    单态模式的设计和应用

    单态模式(Singleton Pattern)是一种常用的软件设计模式,它的核心目标是确保一个类在整个应用程序中只有一个实例,并提供全局唯一的访问点。这种模式在资源管理、配置管理、对象协调等方面有广泛应用,例如创建...

    单态模式和工厂模式.ppt

    **单态模式(Singleton Pattern)** 单态模式是一种创建型设计模式,其核心在于保证一个类只有一个实例,并提供一个全局访问点。这种模式的主要目的是为了节约系统资源,避免频繁地创建和销毁对象,同时提供了一个...

    设计模式一点通之单态模式

    单态模式(Singleton Pattern)是设计模式中的一种基础模式,主要用来确保一个类只有一个实例,并提供一个全局访问点。在软件工程中,当一个类只能有一个实例而且客户可以从一个众所周知的访问点访问它时,这样的...

    单态模式和简单工厂模式

    单态模式(Singleton Pattern)和简单工厂模式(Simple Factory Pattern)是软件设计中常见的两种创建型设计模式。在Java编程中,它们都是为了简化对象的创建过程,但各自有着不同的应用场景和特点。 单态模式是一...

    单态模式的练习

    单态模式(Singleton Pattern)是设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这个模式通常用于控制资源的共享,比如数据库连接、线程池或者配置对象等。在Java或其他面向对象...

    mfc单态模式的例子

    单态模式(Singleton Pattern)是设计模式中的一种,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。在MFC(Microsoft Foundation Classes)框架中,单态模式的应用同样重要,尤其对于需要全局共享的...

    设计模式一点通之单态模式 C++

    单态模式(Singleton Pattern)是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。这种模式在需要频繁创建和销毁对象,且只允许存在一个实例的情况下非常有用,例如配置管理、线程池、缓存...

    PHP单态模式简单用法示例

    在软件设计中,单态模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。PHP中的单态模式实现通常涉及将类的构造函数设置为私有(private)和静态...

    有关static block静态代码块和单态设计模式

    单态设计模式(Singleton Pattern)是一种常见的软件设计模式,它的目标是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处包括资源管理的有效性、性能优化以及简化多线程环境下的同步控制。在Java中,...

    Java中23种设计模式(个人整理实用).doc

    4. 单态模式(Singleton Pattern) 单态模式是一种创建型设计模式,它提供了一种创建对象的接口,确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。 5. 原型模式(Prototype Pattern) 原型模式是一...

    Java语言中的构造方法私有化.pdf

    Java语言中的构造方法私有化是一种常见的编程技巧,主要用于实现特定的设计模式,如单态模式(Singleton Pattern)。在Java中,私有构造方法是通过将构造函数声明为private来实现的,这使得其他类无法直接实例化该类...

    Java23种设计模式(总结).doc

    1.1.4 单态模式(Singleton Pattern) 单态模式是一种创建型模式,它提供了一种方式来创建一个类的唯一实例,确保任何时候都只有一个实例存在。 1.1.5 原型模式(Prototype Pattern) 原型模式是一种创建型模式,...

    完整版 Java高级教程 Java语言程序设计 第6章 常用设计模式(共25页).ppt

    1. 单态模式(Singleton Pattern): 单态模式确保一个类只有一个实例,并提供全局访问点。这种模式在资源管理(如数据库连接)中特别有用,以避免并发环境中资源的重复创建和管理。单态模式有饿汉式和懒汉式两种...

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

    根据给定的信息,《Head First 设计模式》这本书将单件模式(也称为单例或单态模式)作为其中的一个重点章节进行讲解。单件模式是一种常用的创建型设计模式,其目的是控制类的实例化过程,确保在整个应用程序中,一...

    二十三种设计模式【PDF版】

    设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. ...

    java笔试程序分类总结

    1. **单态模式(Singleton Pattern)**: - 单态模式是一种设计模式,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点。在Java中,通常通过以下两种方式实现单态模式: - **饿汉式(Eager ...

    singleton.rar_软件设计/软件工程_Java_

    单态模式(Singleton Pattern)是软件设计模式中最基础且常用的一种模式,主要目的是控制类的实例化过程,确保一个类在整个应用程序中只有一个实例,并提供一个全局访问点。这个模式在Java编程中尤其常见,因为Java...

Global site tag (gtag.js) - Google Analytics