论坛首页 Java企业应用论坛

DesignPattern学习-----Singleton

浏览 10163 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-17  

   学习了Java两个月。。之后两个月学习jsp,servlet,sql,html一堆杂七杂八的东西。又花一个多月复习了一下。。。
    之后一个偶然的机会,跑J道里逛了逛。。banq老大强调oo思想,设计模式。。于是开始学习设计模式 :D
    刚开始学。。好多东西都不是那么明白。。。有理解错误的地方还请多多指教。。。

    我从Singleton开始学。。我是这么理解的。。

    Singleton顾名思义就是只能创建一个实例对象。。所以不能拥有public的构造方法。。

java 代码

  1. public class Singleton{   
  2.        private Singleton(){}   
  3. }  

既然构造方法是私有的,那么从外面不可能创建Singleton实例了。。只能从内部创建。。所以需要一个方法来创建此实例。。此方法肯定必须是static的。。

 

java 代码
  1. public class Singleton{      
  2.        private Singleton(){}      
  3.        
  4.        public static Singleton getInstance(){   
  5.             return [Singleton Instance];   
  6.       }   
  7. }   

getInstance方法要返回一个Singleton实例。。就要一个Singleton类型的变量来存储。。声明一个Singleton类型的属性。。同样需要是static 的。。静态方法只能访问静态属性。。。

java 代码
  1. public class Singleton{      
  2.        private Singleton(){}      
  3.        
  4.        public static Singleton getInstance(){   
  5.             single=new Singleton();   
  6.             return single;   
  7.       }   
  8.       private static Singleton single;   
  9. }   

如此就能获得Singleton的实例了。。但是并不能确保只生成一个实例。。。需做判断。。。

java 代码
  1. public class Singleton{      
  2.        private Singleton(){}      
  3.        
  4.        public static Singleton getInstance(){   
  5.            if(single==null){   
  6.                 single=new Singleton();   
  7.            }   
  8.            return single;   
  9.        }   
  10.       private static Singleton single;   
  11. }   

这样就可以了。。。

接着就牵扯到了线程问题。。。假设有两个线程。。thread1,thread2。。thread1运行到第5行,然后跳到了thread2。。也运行到第5行之后。。。此时两线程都得到single为空。。。那么就会有两个实例了。。。解决办法。。同步。。

java 代码
  1. public class Singleton{         
  2.        private Singleton(){}         
  3.           
  4.        public synchronized static Singleton getInstance(){      
  5.            if(single==null){      
  6.                 single=new Singleton();      
  7.            }      
  8.            return single;      
  9.        }      
  10.       private static Singleton single;      
  11. }      

 

还有一种方法,提前实例化。。。

java 代码
  1. public class Singleton{         
  2.        private Singleton(){}         
  3.           
  4.        public static Singleton getInstance(){      
  5.                   return single;      
  6.        }      
  7.       private static Singleton single=new Singleton();      
  8. }      

 

此时single的static修饰符有起到另一个作用。。。因为static类型的属性,只在类加载时初始化一次。。。以后不会再初始化了。。确保了只有一个实例。。。

最后一种方法是再head first design pattern上看到的。。double-checked locking。。。

java 代码
  1. public class Singleton{         
  2.        private Singleton(){}         
  3.           
  4.        public static Singleton getInstance(){      
  5.            if(single==null){      
  6.                synchronized(Singleton.class){   
  7.                   if(single==null){      
  8.                      single=new Singleton();      
  9.                   }   
  10.                }   
  11.            }      
  12.            return single;      
  13.        }      
  14.       private volatile static Singleton single;      
  15. }      

 

目前对Singleton的理解就这么多。

 

   发表时间:2007-12-17  
Double checked lock也还是不能保证线程安全的。在多核机或者某些jvm实现上,由于指令乱序执行的可能性,还是有可能导致生成多个实例。。。

另外,还有一种singleton的实现方法
class Singleton{
    class SingletonHolder{
       private static Singleton instance = new Singleton()
    }
    private Singleton(){}
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

好像是这样吧,这个有点意思,呵呵
0 请登录后投票
   发表时间:2007-12-17  
BlueGuitar 写道
class Singleton{
    class SingletonHolder{
       private static Singleton instance = new Singleton()
    }
    private Singleton(){}
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}




你的代码应该加上对SingletonHolder的static声明。

另外,你是否能解释你提供的代码和以下代码的本质区别,这才是有意思的地方

class Singleton{   
     
    private static Singleton instance = new Singleton();  
    private Singleton(){}   
    public synchronized static Singleton getInstance(){   
        return instance ;   
    }   
}   
0 请登录后投票
   发表时间:2007-12-17  
呵呵,这个要思考一下么,说出来就没意思啦。
0 请登录后投票
   发表时间:2007-12-17  
BlueGuitar 写道
呵呵,这个要思考一下么,说出来就没意思啦。
加上static之后,就成了静态内部类,保证了在jvm中仅有一个实例。
而且当这么一弄,也会有延迟加载的作用。
0 请登录后投票
   发表时间:2007-12-17  
我晕,引乱了
0 请登录后投票
   发表时间:2007-12-18  
the details of DCL is from Bob Lee's Blog:
http://crazybob.org/2007/01/lazy-loading-singletons.html
0 请登录后投票
   发表时间:2007-12-19  
在两个jvm上也不能保证单例。。。书上也提过。。。
不过没说解决办法。。只说别再两个jvm上运行
0 请登录后投票
   发表时间:2007-12-19  
甭说2个jvm,在同一个jvm中的2个classloader中也不能实现单例。这个模式水很深....
0 请登录后投票
   发表时间:2007-12-19  
唉。。
肤浅了。。。
开始还以为挺简单
0 请登录后投票
论坛首页 Java企业应用版

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