java单例模式二
原文地址:http://balan.javaeye.com/blog/164873
一、定义
单例模式(Singleton pattern):确保一个类只有一个实例,并提供一个全局的访问点。
这个定义包含两层意思:
第一:我们把某个类设计成自己管理的一个单独实例,同时也要避免其他类再自行产生实例。要想取得单个实例,通过单例类是唯一的途径。
第二:我们必需提供对这个实例的全局访问点:当你需要实例时,向类查询,它会给你返回单个实例。
注意:单例模式确保一个类只有一个实例,是指在特定系统范围内只能有一个实例。有时在某些情况下,使用Singleton并不能达到Singleton的目的,如有多个Singleton对象同时被不同的类装入器装载;在EJB这样的分布式系统中使用也要注意这种情况,因为EJB是跨服务器,跨JVM的。
1。某个框架容器内:如Spring IOC容器,可以通过配置保证实例在容器内的唯一性。
2。再如单一JVM中、单一类加载器加载类的情况可以保证实例的唯一性。
如果在两个类加载器或JVM中,可能他们有机会各自创建自己的单个实例,因为每个类加载器都定义了一个命名空间,如果有两个以上的类加载器,不同的类加载器可能会加载同一个类,从整个程序来看,同一个类会被加载多次。如果这样的事情发生在单例上,就会产后多个Singleton并存的怪异现象。所以如果你的程序有多个类加载,同时你又使用了单例模式,请一定要小心。有一个解决办法是,自行给单例类指定类加载器(指定同一个类加载器)。
二、用处
有一些对象其实我们完全只需要一个即可,如:线程池(threadpool)、缓存(cache)、注册表(registry)的对象、设备的驱动程序的对象等等。事实上,这些类的对象只能有一个实例,如果制造出多个实例,就会导致许多问题的产生,例如:程序的行为异常、资源的过量使用、产生不一致的结果等等。Java Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。
三、Java Singleton模式常见的几种形式
一)。使用立即创建实例,而不用延迟实例化的做法
1。使用全局变量
- //readResolve 方法维持了Singleton的单例属性private Object readResolve() throws ObjectStreamException{return uniqueInstance;}
?再进行测试:输出结果为true
?
反序列化之后新创建的对象会先调用此方法,该方法返回的对象引用被返回,取代了新创建的对象。本质上,该方法忽略了新建对象,仍然返回类初始化时创建的那个实例。