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

singleton单态模式的实现方式

阅读更多
    参看了crazybob的关于单态模式的文章http://crazybob.org/2007/01/lazy-loading-singletons.html,非常受益。最近在学习设计模式,有必要整理下singletion的几种实现方式:
     简单说来,大体是有三种实现方式:
1、饿汉式 在下面这个例子中,这个类被加载时,静态变量m_instance 会被初始化,此时类的私有构造子会被调用。这时候,单例类的惟一实例就被创建出来了。
//饿汉式:     
public class EagerSingleton {  
/** @label Creates */     
private static final EagerSingleton m_instance = new EagerSingleton(); 
/** 
* 私有的默认构造函数 
*/ 
private EagerSingleton() { }    

/** 
* 静态工厂方法 
*/   
public static EagerSingleton getInstance() {     
return m_instance;     
}  
} 

2、懒汉式
Java代码
//懒汉式    
//使用到才实例化 不使用不实例化,比如你使用此类的其他静态方法 而饿汉式只要用到就被实例化   
public class LazySingleton        
{        
private LazySingleton() { }       
  
//对静态工厂方法使用了同步化,以处理多线程环境   
public synchronized static LazySingleton getInstance()        
{        
   if (m_instance == null)        
   {        
       m_instance = new LazySingleton();        
   }        
   return m_instance;        
  }       
}   


注:(1)、从资源利用效率角度来讲,饿汉式比懒汉式单例类稍差些。
  (2)、从速度和反应时间角度来讲,饿汉式比懒汉式单例类稍好些。
3、登记式
Java代码
//登记式:          
import java.util.HashMap;    
public class RegSingleton    
{    
  static private HashMap m_registry = new HashMap();    
  static    
  {    
    RegSingleton x = new RegSingleton();    
    m_registry.put( x.getClass().getName() , x);    
  }    
  /**   
  * 保护的默认构造子   
  */    
  protected RegSingleton() {}    
  /**   
  * 静态工厂方法,返还此类惟一的实例   
  */    
  static public RegSingleton getInstance(String name)    
  {    
    if (name == null)    
    {    
      name = "com.javapatterns.singleton.demos.RegSingleton";    
    }    
  if (m_registry.get(name) == null)    
  {    
    try    
    {    
       m_registry.put( name,Class.forName(name).newInstance() ) ;    
    }    
    catch(Exception e)    
    {    
       System.out.println("Error happened.");    
    }    
   }    
   return (RegSingleton) (m_registry.get(name) );    
  }    
   /**   
   * 一个示意性的商业方法   
   */    
   public String about()    
   {    
      return "Hello, I am RegSingleton.";    
   }   
}   
     

它的子类RegSingletonChild 需要父类的帮助才能实例化。
Java代码
import java.util.HashMap;    
public class RegSingletonChild extends RegSingleton    
{    
  public RegSingletonChild() {}    
  /**   
  * 静态工厂方法   
  */    
  static public RegSingletonChild getInstance()    
  {    
    return (RegSingletonChild)    
    RegSingleton.getInstance( "com.javapatterns.singleton.demos.RegSingletonChild" );    
}    
  /**   
  * 一个示意性的商业方法   
  */    
  public String about()    
  {    
    return "Hello, I am RegSingletonChild.";     
  }   
}  

缺点:
1、RegSingletonChild类的构造函数是public,就等于允许了以这样方式产生实例而不在父类的登记中。

2、GoF 曾指出,由于父类的实例必须存在才可能有子类的实例,这在有些情况下是一个浪费。


下面我们接着补充:
    我们使用的多为前两种方式:饿汉式和懒汉式。究竟选择哪一个,我们这里有一个原则。在系统上线使用时,你一般都需要一次性加载所有的单态,以便于尽早发现可能出现的问题;而在开发和测试阶段,你只是需要加载那些必须的单态而不会浪费时间。

    针对懒汉式(用到时加载),我们进一步拓展开来:上面给的代码实现方式,是使用原始的老的线程同步机制,以保证线程安全。
    在java 1.5 之后,出现了volatile 关键字,此关键字能保证其修饰的变量不允许有不同于“主”内存区域(Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3)的变量拷贝,换句话说,一个变量经volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即获取到了相同的值。
    接着就有了基于Double-Checked Locking(DCL)的懒汉式,这种方式通过“主”内存区对volatile修饰的变量域进行检查,并且在必要的时候进行加锁。
public class Singleton {
	private volatile Singleton instance;
	
	private Singleton(){}
	
	public Singleton getInstance(){
		if(null == instance){
			synchronized (Singleton.class) {
				if(null == instance)
					instance = new Singleton();
			}
		}
		return instance;
	}
}

    但DCL方式的懒汉,使用并不广泛,因为相比较传统的方法加锁机制,DCL方式并不快多少。所以大多数人仍在使用传统的方式。
     但现在有一种懒汉方式,非常的流行,采取的是Initialization on Demand Holder(IODH),此方式代码量不多,并且线程同步问题解决的非常完美。代码如下:
public class Singleton {
	private static class SingletonHolder{
		private static Singleton instance = new Singleton();
	}
	private Singleton(){}
	public static Singleton getInstance(){
		return SingletonHolder.instance;
	}
}

    单例模式,先学到这里。还有巨多的模式等着我呢,慢慢来。。。
分享到:
评论

相关推荐

    单态模式(代码)

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

    JAVA设计模式(单态模式和简单工厂模式)

    单态模式的定义: Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 在项目的很多地方都会用到它,比如说数据库的链接。 使用Singleton的好处还在于可以节省内存,因为它限制了实例...

    单态模式(PPT)

    在提供的代码示例中,展示的是饿汉式的单态模式实现。具体如下: ```java package org.singleton; // 单态设计模式 class Singleton3 { // 私有构造函数防止外部直接实例化 private Singleton3() {} // 静态...

    设计模式之Singleton(单态)

    ### 单态模式的实现方式 #### 1. 饿汉式(静态初始化) ```java public class Singleton { // 在类加载时初始化实例,保证多线程环境下的安全性 private static Singleton instance = new Singleton(); ...

    Net单态模式的案例

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

    .Net单态模式的案例

    下面将详细阐述单态模式的原理、实现方式以及它在三层架构中的应用。 首先,理解单态模式的基本结构。单态模式包含一个私有的构造函数,以防止外部直接创建实例,同时提供一个静态方法或属性来获取这个唯一的实例。...

    单态模式的练习

    二、单态模式的实现方式 1. 饿汉式(Eager Initialization):在类加载时就初始化,所以是线程安全的。代码如下: ```java public class Singleton { private static final Singleton INSTANCE = new Singleton(); ...

    单态模式的设计和应用

    总的来说,单态模式是一种强大的设计模式,但使用时应权衡其优缺点,并根据具体应用场景选择合适的实现方式。在某些情况下,如依赖注入框架或使用枚举类型替代,可以避免单态模式带来的复杂性。

    mfc单态模式的例子

    2. **MFC中的单态模式实现** 在MFC中,通常使用`CWinApp`类作为应用程序的单例,因为每个MFC程序只有一个`CWinApp`实例。不过,我们也可以为自定义类实现单例模式。以下是一种常见的实现方式: - **私有化构造...

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

    实现单态模式主要有两种方式:饿汉式和懒汉式。 1. 饿汉式(Eager Initialization): 饿汉式是在类加载时就完成了实例化,避免了线程同步问题。因为实例在类加载时就创建,所以是线程安全的。代码通常如下: ``...

    单态模式和简单工厂模式

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

    Java设计模式之单态模式(Singleton模式)介绍

    以下是两种常见的单态模式实现方式: 1. 饿汉式(Eager Initialization): 这种方式在类加载时就完成了初始化,所以类加载比较慢,但获取实例的速度快,且线程安全。如: ```java public class Singleton { ...

    单态模式和工厂模式.ppt

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

    DataSource的单态模式(SingleTon)程序---马克-to-win java视频

    DataSource的单态模式(SingleTon)程序---马克-to-win java视频 数据源 单态模式 dataSource Singleton

    Java中单态设计模式

    通过上述的教学过程设计,学生不仅能够理解单态设计模式的基本原理,还能了解到其实现的具体步骤及其在实际项目中的应用场景。更重要的是,这种方法能够帮助学生建立起面向对象编程的思想,为他们未来的学习和发展...

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

    在C++中实现单态模式,通常有几种常见的方式: 1. **懒汉式(Lazy Initialization)**: 这种方式延迟到第一次使用时才创建单例对象。为了确保线程安全,通常会使用`std::call_once`或者`std::mutex`来控制初始化...

    单态模式1---马克-to-win Java视频

    单态模式 马克-to-win Java视频 Singleton 单例模式

    单态模式2---马克-to-win java视频

    单态模式 马克-to-win java视频 Singleton 单例模式

    单态模式3---马克-to-win java视频

    单态模式 马克-to-win java视频 Singleton 单例模式

    Java实现的单态登陆

    1. **单态模式实现**: - 在Java中,我们通常通过私有构造函数和一个静态方法来创建并返回单例对象。以下是一个简单的单例模式实现: ```java public class SingletonLogin { private static SingletonLogin ...

Global site tag (gtag.js) - Google Analytics