Singleton的几种形式

Singleton能确保某一个类只有一个实例。

饿汉式:被加载时即实例化,从资源利用效率来看,较懒汉式稍差;从速度和反应时间看,较懒汉式稍好些。它不能在C++内实现。
EagerSingleton.java

java 代码
 
  1. public class EagerSingleton{  
  2. //私有field,并实自身例化  
  3.     private static final EagerSingleton instance=new EagerSingleton();  
  4. /* 
  5. *   私有构造子,确保外界不能实例化。同时意味着它不能被子类继承。 
  6. */  
  7.     private EagerSingleton(){}  
  8. /* 
  9. *   静态工厂方法,返回此类的实例 
  10. */  
  11.     public static EagerSingleton getInstance(){  
  12.         return this.instance;  
  13.     }  
  14. /* 
  15. *   示意商业逻辑 
  16. */  
  17.     public void about(){  
  18.         System.out.println("This is the EagerSingleton pattern.");  
  19.     }  
  20. }  

懒汉式:如果加载器是静态的,被加载时不会将自己实例化,直到第一次引用时才实例化(即getInstance()时)。它能在C++内实现。
LazySingleton.java
java 代码
  1. public class LazySintleton{  
  2. //私有的field,设为null  
  3.     private static final LazySintleton instance=null;  
  4. /* 
  5. *   私有构造子,确保外界不能实例化。同时意味着它不能被子类继承。 
  6. */  
  7.     private LazySintleton(){}  
  8. /* 
  9. *   静态工厂方法,返回此类的实例 
  10. */  
  11.     public static LazySintleton getInstance(){  
  12.         if(instance==null){
  13.              instance=new LazySingleton();
  14.         }
  15.         return this.instance;  
  16.     }  
  17. /* 
  18. *   示意商业逻辑 
  19. */  
  20.     public void about(){  
  21.         System.out.println("This is the LazySingleton pattern.");  
  22.     }  
  23. }  

值得注意的是,懒汉式在多线程的环境下需要考虑解决线程安全的问题。
下面做些修改

  1. public class LazySintleton{  
  2. //私有的field,设为null  
  3.     private static final LazySintleton instance=null;  
  4. /* 
  5. *   私有构造子,确保外界不能实例化。同时意味着它不能被子类继承。 
  6. */  
  7.     private LazySintleton(){}  
  8. /* 
  9. *   静态工厂方法,返回此类的实例
  10. *   在多线程下加个管程(方法声名中使用synchronized关键字)
  11. */ 
  12.     public static synchronized LazySintleton getInstance(){
  13.         if(instance==null){
  14.              instance=new LazySingleton();
  15.         }
  16.         return this.instance;  
  17.     }  
  18. /* 
  19. *   示意商业逻辑 
  20. */  
  21.     public void about(){  
  22.         System.out.println("This is the LazySingleton pattern.");  
  23.     }  


登记式:GoF为克服懒汉式单例类不能继承的缺点而设计的。注意此处的父类与子类的实现。
RegSingleton.java
java 代码
 
  1. import java.util.HashMap;  
  2. public class RegSingleton{  
  3.     static private HashMap registry=new HashMap();  
  4.     static {  
  5.         RegSingleton x=new RegSingleton();  
  6.         registry.put(x.getClass().getName(),x);  
  7.     }  
  8.     /* 
  9.      *保护的构造子 
  10.      */  
  11.     protected Regsingleton(){}  
  12.       
  13.     /** 
  14.      *静态工厂方法,返还此类唯一的实例 
  15.      */  
  16.     public static RegSingleton getInstance(String name){  
  17.         if(name==null){  
  18.             name="RegSingleton";  
  19.         }  
  20.         if(registry.get(name)==null){  
  21.             try{  
  22.                 registry.put(Class.forName(name).newInstance());  
  23.             }  
  24.             catch(Exception e){  
  25.                 System.out.println ("Error:" +e.toString());                  
  26.             }  
  27.         }  
  28.         return (RegSingleton)(registry.get(name));  
  29.     }  
  30.     /** 
  31.      *示意性商业逻辑 
  32.      */  
  33.     public void about(){  
  34.         System.out.println ("This is a base Class of RegSingleton ");  
  35.     }  
  36. }  
子类的实现
RegSingletonChild.java
java 代码
 
  1. import java.util.HashMap;  
  2. public class RegSingletonChild extends RegSingleton{  
  3.     public RegSingleChild(){}  
  4.     /** 
  5.      *静态工厂方法 
  6.      */  
  7.      public static RegSingletonChild getInstance(){  
  8.         return(RegSingleChild)RegSingleton.getInstance("RegSingletonChild");  
  9.      }  
  10.      /** 
  11.       *示意性商业逻辑 
  12.       */  
  13.       public void about(){  
  14.         System.out.println ("This is the child Class extends from RegSingleton class.")  
  15.       }  
  16. }  

一个用内部类实现的Singleton,由Jeremy Manson和Brian Goetx于2004年发布。
Singleton.java
java 代码
 
  1. public class Singleton{  
  2.     /** 
  3.      *通过内部类实例化 
  4.      */  
  5.     static class SingletonHolder{  
  6.         static Singleton instance=new Singleton();  
  7.     }  
  8.     private Singleton(){}  
  9.       
  10.     public static Singleton getInstance(){  
  11.         return SingletonHolder.instance;  
  12.     }  
  13.     public void about(){  
  14.         System.out.println ("test...");  
  15.     }  
  16. }  

在任何使用了EJB、RMI、JINI技术的分散式系统中,应当避免使用有状态的单例。
Edit[2007-4-9]
参考自《java与模式》阎宏。
《java与模式》是本不可多得的好书,值得珍藏!

你可能感兴趣的:(java,设计模式,多线程,c,ejb)