分享

Java设计模式 之 Singleton

 Go_Ahead 2012-12-25
        单例模式(singleton design pattern)也是常用的设计模式之一,使用单例模式就是要保证某个类在整个应用中只有一个实例存在,而且就在其本类中实例化。这样在应用中就不会同时出现某个类的多个实例,就保证了资源的合理利用。
        单例模式看上去虽然简单,却也分好几中,下面就详细看看各种单例模式的区别所在:
------预先加载法------------------------------------------------------------
这种实现方式是单例模式的最简单的一种,把构造函数写成私有的(private),这样就不能再其他的类里实例化该类,然后在类中提供一个静态的实例
public class SingletonTest(){
           //静态的实例
           private static final SingletonTest testInstance =new SingletonTest ();
           //一个私有的构造器
           private SingleTest(){
 
           }
           //通过调用此方法来得到SingletonTest 类的实例
           public static SingletonClass getSingletonInstance(){
                       return testInstance;
           }
}
可思考一下这种简单的方法,我们本想让外面调用了getSingletonInstance()此方法才会创建一个实例,其实不论怎样,就算我们没有调用getSingletonInstance()这个方法,SingletonTest的实例任然会被创建,这样就会造成资源浪费。
--------延迟加载法---------------------------------------------------------------
使用延迟加载的方式就能解决上面的问题,它会保证只有外界在调用getSingletonInstance()才方法时才创建一个实例,请看
public class SingletonTest(){
            private static SingletonTest testInstance = null;
 
            private SingleTest(){
            }
            public static SingletonTest getSingletonInstance(){
                        if(testInstance  == null){
                                               testInstance = new SingletonTest();
                        }
                       return  testInstance;
            }
}
区别:
         静态实例变量 testInstance 初始化为null 
         获取实例的方法getSingletonInstance()中,要先判断testInstance  是否为空,如果为空(第一次的时候)才new一个SingletonTest实例,而第二次再调用的时候,因为testInstance 是static的,所以,此时就不为null了,直接返回该实例
--------多线程的情况(同步)---------------------------------------------------------------
第二种(延迟加载)单例模式的实现,在单线程的情况下是没有什么问题,如果是多线程的情况下就有问题了,所以就要加锁,如下
public class SingletonTest{
           private static SingletonTest testInstance = null;
           private SingletonTest(){
           }
           //给获取实例的方法加上【同步锁】
           public synchronized static SingletonTest getSingletonInstance(){
                      if(testInstance == null){
                                   testInstance = new SingletonTest();
                      }
                      return testInstance;
           }
}
给getSingletonInstance()方法加上同步锁以后,如果有多个线程,那么其他线程必须等前面的线程创建完成后才能调用此方法
--------解决加了synchronized 以后,性能慢的问题------------------------------------
因为加了synchronized修饰的同步块可是要比一般的代码段上几倍的,如果怎的有很多线程,那么就会调用多次 getSingletonInstance()方法,那就要马上考虑这个所引起的性能问题了,【因为第三种 是 在整个方法上都加了锁,而实际上呢,我们加锁的真正原因就是在检查testInstance  是否为null的操作
public class SingletonTest{
private static SingletonTest testInstance = null;
private SingletonTest(){
}      
public static SingletonTest getSingletonInstance(){
                     if(testInstance == null){
                                       //只有当testInstance真的为null的时候才给后面的判断的那块加上【同步锁】,这样性能上才会得到优化
                                      synchronized (SingletonTest.class){
                                      if(testInstance == null){
                                                    testInstance = new SingletonTest();
                                       }
                              }
                 }
                    
                 return testInstance;
}
 
}
注意:一定不能把同步锁把判断testInstance  为null加锁
 
 
 
 
 
 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多