Singleton的几种形式

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

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

java 代码
 
public class EagerSingleton{   //私有field,并实自身例化       private static final EagerSingleton instance=new EagerSingleton();   /*  *   私有构造子,确保外界不能实例化。同时意味着它不能被子类继承。  */       private EagerSingleton(){}   /*  *   静态工厂方法,返回此类的实例  */       public static EagerSingleton getInstance(){           return this.instance;       }   /*  *   示意商业逻辑  */       public void about(){           System.out.println("This is the EagerSingleton pattern.");       }   }  

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

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

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

登记式:GoF为克服懒汉式单例类不能继承的缺点而设计的。注意此处的父类与子类的实现。
RegSingleton.java
java 代码
 
import java.util.HashMap;   public class RegSingleton{       static private HashMap registry=new HashMap();       static {           RegSingleton x=new RegSingleton();           registry.put(x.getClass().getName(),x);       }       /*       *保护的构造子       */       protected Regsingleton(){}              /**       *静态工厂方法,返还此类唯一的实例       */       public static RegSingleton getInstance(String name){           if(name==null){               name="RegSingleton";           }           if(registry.get(name)==null){               try{                   registry.put(Class.forName(name).newInstance());               }               catch(Exception e){                   System.out.println ("Error:" +e.toString());                               }           }           return (RegSingleton)(registry.get(name));       }       /**       *示意性商业逻辑       */       public void about(){           System.out.println ("This is a base Class of RegSingleton ");       }   }  
子类的实现
RegSingletonChild.java
java 代码
 
import java.util.HashMap;   public class RegSingletonChild extends RegSingleton{       public RegSingleChild(){}       /**       *静态工厂方法       */        public static RegSingletonChild getInstance(){           return(RegSingleChild)RegSingleton.getInstance("RegSingletonChild");        }        /**        *示意性商业逻辑        */         public void about(){           System.out.println ("This is the child Class extends from RegSingleton class.")         }   }  

一个用内部类实现的Singleton,由Jeremy Manson和Brian Goetx于2004年发布。
Singleton.java
java 代码
 
public class Singleton{       /**       *通过内部类实例化       */       static class SingletonHolder{           static Singleton instance=new Singleton();       }       private Singleton(){}              public static Singleton getInstance(){           return SingletonHolder.instance;       }       public void about(){           System.out.println ("test...");       }   }  

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值