Java单例模式探究.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《Java单例模式探究.pdf》由会员分享,可在线阅读,更多相关《Java单例模式探究.pdf(9页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、http:/ 疯狂大白菜 1/9 Java 单例模式探究单例模式探究单例模式探究单例模式探究 作为对象的创建模式作为对象的创建模式作为对象的创建模式作为对象的创建模式GOF95,单例模式确保某个类只有一个实例单例模式确保某个类只有一个实例单例模式确保某个类只有一个实例单例模式确保某个类只有一个实例,而且自行实例化并向而且自行实例化并向而且自行实例化并向而且自行实例化并向整个系统提供这个实例整个系统提供这个实例整个系统提供这个实例整个系统提供这个实例。这个类称为单例类这个类称为单例类这个类称为单例类这个类称为单例类。由定义可以总结出单例模式的要点有三个由定义可以总结出单例模式的要点有三个由定义可
2、以总结出单例模式的要点有三个由定义可以总结出单例模式的要点有三个:一是单例类只能有一个实例一是单例类只能有一个实例一是单例类只能有一个实例一是单例类只能有一个实例;二是它必须自行创建这个实例二是它必须自行创建这个实例二是它必须自行创建这个实例二是它必须自行创建这个实例;三是它必须自行向整个系统三是它必须自行向整个系统三是它必须自行向整个系统三是它必须自行向整个系统提供这个实例提供这个实例提供这个实例提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个 Print
3、er Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。虽然从类图上看,单例模式是最简单的设计模式之一,但是真正正确地使用单例模式却不是那么简单的事。首先看一个经典的单例实现。public class Singleton private static Singleton uniqueInstance=null;private Singleton()/Exists only to defeat instantiation.public
4、static Singleton getInstance()if(uniqueInstance=null)uniqueInstance=new Singleton();return uniqueInstance;/Other methods.Crazy Cabbagehttp:/ 疯狂大白菜 2/9 Singleton 通过将构造方法限定为 private 避免了类在外部被实例化,在同一个虚拟机范围内,Singleton 的唯一实例只能通过 getInstance()方法访问。(事实上,通过 Java 反射机制是能够实例化构造方法为 private 的类的,那基本上会使所有的 Java 单例实
5、现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个 Singleton 实例。有很多种方法可以实现线程安全的单例模式,下面逐一介绍:1 一步到位的
6、饿汉单例类 饿汉式单例类是在 Java 语言里实现得最为简便的单例类。在类被加载时,就会将自己实例化。public class Singleton private static Singleton uniqueInstance=new Singleton();private Singleton()/Exists only to defeat instantiation.public static Singleton getInstance()return uniqueInstance;/other methods.2 改造经典模式 首先是最简单最直接的改造。public class Singl
7、eton private static Singleton uniqueInstance=null;private Singleton()/Exists only to defeat instantiation.public synchronized static Singleton getInstance()if(uniqueInstance=null)uniqueInstance=new Singleton();Crazy Cabbagehttp:/ 疯狂大白菜 3/9 return uniqueInstance;/Other methods.通过 synchronized 关键字,同步了
8、不同线程对 getInstance()的访问。这就是所谓的懒汉模式。与饿汉式单例类不同的是,懒汉式单例类在第一次被引用时将自己实例化。这种简单实现的问题在于,每次访问 getInstance()都需要同步操作,而事实上同步只在第一次访问时有意义。为了避免不必要的同步操作,在 JDK1.5以后可以使用一种双重检查加锁的方法。public class Singleton /volatile is very important for uniqueInstance consistency.private volatile static Singleton uniqueInstance=null;pr
9、ivate Singleton()/Exists only to defeat instantiation.public static Singleton getInstance()/first check no need to synchronize.if(uniqueInstance=null)/second check need to synchronize,but only run limit times.synchronized(Singleton.class)if(uniqueInstance=null)uniqueInstance=new Singleton();return u
10、niqueInstance;/Other methods.volatile 确保 uniqueInstance 被初始化为单例后的改变对所有线程可见,多线程能够正确处理 uniqueInstance 变量。getInstance()中包含两次判空操作,第一次判空每次访问都会执行,而第二次判空只在初始访问存在大量并发的情况下出现。通过两次判空避免了不必要的线程同步。之所以限制必须在 JDK1.5 后使用是因为,之前的 Java 存储模型不能保证 volatile 语义的完全正确实现。为了突破Crazy Cabbagehttp:/ 疯狂大白菜 4/9 这种限制Effective Java中给出了一
11、种精妙的解决方法,充分利用了 Java 虚拟机的特性。public class Singleton /an inner class holder the uniqueInstance.private static class SingletonHolder static final Singleton uniqueInstance=new Singleton();private Singleton()/Exists only to defeat instantiation.public static Singleton getInstance()return SingletonHolder.u
12、niqueInstance;/Other methods.When the getInstance method is invoked for the first time,it reads SingletonHolder.uniqueInstance for the first time,causing the SingletonHolder class to get initialized.The beauty of this idiom is that the getInstance method is not synchronized and performs only a field
13、 access,so lazy initialization adds practically nothing to the cost of access.A modern VM will synchronize field access only to initialize the class.Once the class is initialized,the VM will patch the code so that subsequent access to the field does not involve any testing or synchronization.3 登记式单例
14、类 登记式单例类是 GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。public class RegSingleton static private HashMap m_registry=new HashMap();static RegSingleton x=new RegSingleton();m_registry.put(x.getClass().getName(),x);protected RegSingleton()Crazy Cabbagehttp:/ 疯狂大白菜 5/9 public static RegSingleton getInstance(String
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 模式 探究
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内