论坛首页 Java企业应用论坛

Java设计模式-之Singleton单例模式

浏览 9377 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-09-19  

Singleton (单例模式)

 

Intent Ensure a class only has one instance , and provide a global point of access of it.

 

瞎谈:就是保证一个类只有一个实例,并且提供一个全局可访问的点。打个比方,广州限制每户人家养狗,但是只能养一条。一开始你没有狗,你去买一条。若干年后,狗不行失踪了。你为了填补寂寞的空虚,别人又送你一条(或者还是你自己买的)。我们不关注你的狗来源,只保证你家的狗每时每刻就一条。你为了确保以后养狗方便,就到保险公司办了保险,他们承诺,你的狗要是出现意外事故,他们负责陪一条给你。从此,你自由了,狗的事情交给别人了,而且别人也保证只给一条给你。

 

正经:很多时候我们要保证类的实例只有一个。我们可能在自己的代码中判断需要的类的实例有无,无就new一个。这样看似不错。问题是,你用到这个类的地方有n个,这样你就需要n个判断。为什么不把这个职责交给类本身呢?然后让类提供一个接口访问

 

代码实现:

 

public class Singleton

{

private static Singleton singleton=null;

private Singleton()

{}

public static Singleton instance()

{

   if(singleton==null)

      singleton = new Singleton();

   return singleton

      return singleton;

}

}

 

有无问题:碰上多线程怎么办?凉拌了。加锁吧,或者。。。前人总结的经验,有3中方法

1.       直接加锁

public class Singleton

{

private static Singleton singleton=null;

private Singleton()

{}

public static synchronized Singleton instance()

{

   if(singleton==null)

      singleton = new Singleton();

   return singleton

      return singleton;

}

}

2.       早期实例化

public class Singleton

{

private static Singleton singleton = new Singleton();

private Singleton();

public static Singleton getInstance()

{

   return singleton;

}

}

 

3.       双重检测锁

public class Singleton

{

   private volatile static Singleton singleton=null;

   private Singleton(){}

   public static Singleton getInstance()

   {

              if(singleton==null)

        {    synchronized(Singleton.class)

                     {

                           singleton=new Singleton();

                     }

         }

         return singleton;

    }

   发表时间:2009-09-20  

补充一种形式,也是线程安全的:The solution of Bill Pugh

 

 public class Singleton {
   // Private constructor prevents instantiation from other classes
   private Singleton() {}
 
   /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
    * or the first access to SingletonHolder.INSTANCE, not before.
    */
   private static class SingletonHolder { 
     private static final Singleton INSTANCE = new Singleton();
   }
 
   public static Singleton getInstance() {
     return SingletonHolder.INSTANCE;
   }
 }

 

from:http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh

0 请登录后投票
   发表时间:2009-09-20  
不错,这个帖子把Java现有的各种单例模式的实现方式总结的很好
0 请登录后投票
   发表时间:2009-09-21  
还可以再细致一点儿哈,比如阐述一下为什要用单例模式之类的。。。除了所谓的只要一次实例化之类的说辞。。同样用static的话 也能达到同样的效果过啊。。是吧!
0 请登录后投票
   发表时间:2009-09-24  
代码还行,例子感觉不是非常恰当。
0 请登录后投票
   发表时间:2009-09-24  
双检锁那个写的有问题

同步里面还要判断以下,不然可能会重复创建!
0 请登录后投票
   发表时间:2009-09-24  
如果别人使用的类是持续性的,比如session,单单用synchronized肯定不行吧,应该再加上一种情况采用ThreadLocal实现同步的方式
0 请登录后投票
   发表时间:2009-09-25  
anyanyway 写道

补充一种形式,也是线程安全的:The solution of Bill Pugh

 

 public class Singleton {
   // Private constructor prevents instantiation from other classes
   private Singleton() {}
 
   /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
    * or the first access to SingletonHolder.INSTANCE, not before.
    */
   private static class SingletonHolder { 
     private static final Singleton INSTANCE = new Singleton();
   }
 
   public static Singleton getInstance() {
     return SingletonHolder.INSTANCE;
   }
 }

 

from:http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh


这种方式的确在网上有不少美誉,不过我在项目中到时,它的性能差的很多,速度要比正常单例出来的对象慢

0 请登录后投票
   发表时间:2009-09-25   最后修改:2009-09-25
public class Singleton
{
private static Singleton singleton = new Singleton();
private Singleton();
public static Singleton getInstance()
{
   return singleton;
}
}
喜欢用这个,因为C++同步锁有点麻烦
0 请登录后投票
   发表时间:2009-09-25  
在JDK1.6中有枚举(太久没用1.5了,不记得有没有),据说默认就是可序列化并且线程安全的,如果要写单例模式,不如就直接用一个枚举类,多好啊,还自己搞那么多的判断
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics