java设计模式(三)—单例模式
来源:互联网 发布:淘宝售后培训ppt 编辑:程序博客网 时间:2024/05/29 11:24
2.概念
确保一个类只有一个实例,并提供一个全局访问点。
2.作用
(1) 如下对象只能有一个实例,需要用单例。比方说:线程池,缓存,对话框,处理偏好设置和注册表的对象、日志对象,充当打印机、显卡等设备的驱动程序的对象。
(2) 为什么不创建一个类,把所有变量和方法都设为静态的,把该类当成一个单例?
如果类自给自足,不依赖于复杂的初始化,可以这么做。
但静态初始化的控制权在java手上,当有多个类牵扯其中时,会导致一些微妙的,和初始化顺序有关的bug。
(3) 为什么不用全局变量?
全局变量可以提供全局访问,但不能保证只有一个实例。
3.实现方式
3.1 实现类图
3.2 如果getInstance()的性能对应用程序是不很关键,就什么也不做。(我们认为程序一定是多线程的场景)
同步getInstance即简单又有效。但同步一个方法会使程序下降100倍,不宜将getInstance()的程序使用在频繁运行的地方。
public class Singleton{ private static Singleton uniqueInstance; private Singleton{} //构造器是私有的 public static synchronized Singleton getInstance(){ if(uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; }}
如果应用程序总是创建或使用单例,而且在创建和运行时负担不是太重,就可以使用“急切”的方式创建单例。
public class Singleton{ private static Singleton uniqueInstance = new Singleton(); private Singleton{} public static Singleton getInstance(){ return uniqueInstance; }}
在静态初始化器中创建单件,上面这段代码保证了线程安全。
JVM在加载这个类时马上会创建这个唯一的单例。JVM保证在任何线程访问uniqueInstance静态变量之前,一定先创建此实例。
3.4 用“双重检查加锁”,在getInstance()中使用同步
volatile关键词确保:当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确的处理uniqueInstance变量。
public class Singleton{ private volatile static Singleton uniqueInstance; private Singleton{} public static Singleton getInstance(){ if( uniqueInstance == null ){ //检查实例,如果不为空,就进入同步块。 synchronized(Singleton.class){ //只有第一次才彻底执行这里面的代码</span> if( uniqueInstance == null){ //进入区块后,再检查一次,如果仍是null,才创建实例。(再检查的原因是有可能另一个线程已经进来并创 //建了一个实例,这时候就不能再另外创建实例了 uniqueInstance = new Singleton(); } } return uniqueInstance; }}注意:双重加锁不适用于1.4及更早版本的java。1.4及更早版本的许多JVM对于volatile关键字的实现会导致双重加锁失效。
4.注意事项
(1) 如查程序有多个类加载器,又同时使用了单例模式,请小心。有一个解决办法:自行指定类加载器,并指定同一个类加载器。
(2) 单例类的构造器是私有的,不能继承。如果将其改成公有的,就可以被实例化多次,就不是真正的单例了。
0 0
- java设计模式(三)——单例模式
- java设计模式(三)—单例模式
- Java单例设计模式(三)
- java设计模式(三)--单例模式
- Java设计模式(三)--单例模式
- java设计模式(三)---单例模式
- java设计模式——创建型模式专题(三)单例模式
- java设计模式——创建型模式专题(三)单例模式(简版)
- 设计模式(三)单例模式
- 设计模式(三)单例模式
- 设计模式(三):单例模式
- 设计模式(三)单例模式
- 设计模式(三)单例模式
- 设计模式(三) 单例模式
- 设计模式(三):单例模式
- 设计模式(三)单例模式
- java设计模式(三)——单例模式(静态内部类单例模式)
- 设计模式之(三)——单例模式
- 笔记十三(绘制二)
- 相似性度量总结
- 1005.继续(3n+1)猜想
- JUnit简单安装使用步骤总结
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest F. Gourmet and Banquet(贪心+二分)
- java设计模式(三)—单例模式
- leetcode 312 : Burst Balloons
- Android之px、dp、sp之间相互转换
- 【数据结构实验】哈夫曼编/译码
- Android下的驱动开发框架
- 宏定义中的"#"和"##"符号
- Openstack在Centos上安装--(二)Mysql和RabbitMQ的安装与配置
- 1006.换个格式输出整数
- 为什么要进行URL编码