`

OOAD 单例模式

 
阅读更多

 单例模式的要点
  单例单例
  显然单例模式的要点有三个;一是某各类只能有一个实例;二是它必须 自行创建这个事例;三是它必须自行向整个系统提供这个实例。在下面的对象图中,有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。

  资源管理
  一些资源管理器常常设计成单例模式。
  在计算机系统中,需要管理的资源包括软件外 部资源,譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler, 以避免两个打印作业同时输出到打印机中。每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情 况。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。
  需要管理的资源包括软件内部资源,譬如,大多数的软件都有一个(甚至多个)属性(properties)文件存放系统配置。这样的系统应当由一个对象来管理一个属性文件。
  需要管理的软件内部资源也包括譬如负责记录网站来访人数的部件,记录软件系统内部事件、出错信息的部件,或是对系统的表现进行检查的部件等。这些部件都必须集中管理,不可政出多头。
  这些资源管理器构件必须只有一个实例,这是其一;它们必须自行初始化,这是其二;允许整个系统访问自己这是其三。因此,它们都满足单例模式的条件,是单例模式的应用
  一个例子:Windows 回收站
  Windows 9x 以后的视窗系统中都有一个回收站,下图就显示了Windows 2000 的回收站。

  在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。

1.预先加载法

 

class S1 {   
    private S1() {   
        System.out.println("ok1");   
    }   
  
  
    private static S1 instance = new S1();   
  
    public static S1 getInstance() {   
        return instance;   
    }   
}  

 

 

优点:  

 

1.线程安全的

 

2.在类加载的同时已经创建好一个静态对象,调用时反应速度快。

缺点: 资源利用效率不高,可能getInstance永远不会执行到,但是执行了该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化了

 

2.initialization on demand,延迟加载法  (考虑多线程)

 

    class S2 {   
        private S2() {   
            System.out.println("ok2");   
        }   
      
        private static S2 instance = null;   
      
        public static synchronized S2 getInstance() {   
            if (instance == null) instance = new S2();   
            return instance;   
        }   
    }  

 

优点: 资源利用率高,不执行getInstance就不会被实例,可以执行该类其他静态方法。

 


缺点: 第一次加载时发应不快  ,多线程使用不必要的同步开销大

 

3.initialization on demand double check 双重检测( 考虑多线程 )

class S3 {   
    private S3() {   
        System.out.println("ok3");   
    }   
  
    private static S3 instance = null;   
  
    public static S3 getInstance() {   
        if (instance == null) {   
            synchronized (S3.class) {   
                if (instance == null)   
                    instance = new S3();   
            }   
        }   
        return instance;   
    }   
} 

 


 

优点: 资源利用率高, 不执行getInstance就不会被实例,可以执行该类其他静态方法。


缺点: 第一次加载时发应不快  ,由于java 内存模型一些原因偶尔会失败

4.initialization on demand holder  (考虑多线程)

    class S4 {   
        private S4() {   
            System.out.println("ok4");   
        }   
      
        private static class S4Holder {   
            static S4 instance = new S4();   
        }   
      
      
        public static S4 getInstance() {   
            return S4Holder.instance;   
        }   
    }  

 

 

优点: 资源利用率高, 不执行getInstance就不会被实例,可以执行该类其他静态方法。


缺点: 第一次加载时发应不快

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics