写单例模式,总是让我想起孔乙己写“茴香豆”的茴的四种写法,虽然感觉他比较迂腐,但是在说到单例模式时,却也是忍不住的要说单例模式也有好几种写法,这样算来,自己也算迂腐了。不过不管怎样,既然是做技术的,多掌握一点也是比较好的,同时也将积累的分享给大家,大家各凭所好吧。
在说“茴”字之前,需要先说下什么是“茴香豆”,也就是我们的单例模式。单例模式就是让一个对象只产生一个实例,并且对外提供一个全局的方法对其进行调用,通常来说方法名都使使用getInstance()。
再来说说,单例模式的整体架构。
(1)私有的构造函数
(2)私有的静态实例,该实例禁止外部访问。
(3)一个公有的静态工厂方法getInstance(),有时是需要同步的。
(4)有时也可以重写clone()方法。
下面,再来说说,这个“茴”字有几种写法。
第一种,饿汉式,所谓饿汉式就是主动去new一个对象,然后返回。见代码:
/**
* 单例模式之饿汉式
* @author xiAoT
*
*/
public class Singleton001 {
private static Singleton001 instance = new Singleton001();
private Singleton001(){}
public static Singleton001 getInstance(){
return instance;
}
@Override
protected Singleton001 clone() throws CloneNotSupportedException {
return instance;
}
}
饿汉式的缺点是不论使不使用该类,都会在内存中实例化一个对象;优点是因为采用static类型,static本身实现了同步,所以解决了同步的问题,性能比较高,一般情况下推荐使用。
第二种,懒汉式,相当于延迟加载,在需要的时候再创建资源。
/**
* 单例模式之懒汉式
* @author xiAoT
*
*/
public class Singleton002 {
private static Singleton002 instance = null;
private Singleton002(){}
public synchronized static Singleton002 getInstance(){
if(instance == null){
instance = new Singleton002();
}
return instance;
}
}
由于采用了同步,在性能上会打折扣。
第三种,即采用缓存的方式,common.logutil中创建Log类就是采用这个方式,见LogFactory.java。基本实现方式就是用一个Map存放对象,需要使用的时候就从map中取,为了实现同步,我们一般用Hashtable存储。
/**
* 单例模式之采用缓存
* @author xiAoT
*
*/
public class Singleton003 {
private final static String CACHE_KEY = "instance";//定义一个key常量
private Singleton003(){}
private static Hashtable<String,Singleton003> cacheMap = new Hashtable<String, Singleton003>();
public synchronized static Singleton003 getInstance(){
Singleton003 instance = cacheMap.get(CACHE_KEY);
if(instance == null){
cacheMap.put(CACHE_KEY, instance = new Singleton003());
}
return instance;
}
}
第四种,这个方式就神了,即可以实现延迟加载,又能够节省资源,该方式主要采用类级内部类和多线程同步缺省机制实现。
如下几种情况,JDK内部实现了同步:
1. 有static{}修饰的块或者static修改的变量初始化数据;
2. 访问final字段时
3. 在创建线程之前创建对象时
4. 线程可以看见它将要处理的对象时
/**
* 单例模式之采用类级内部类和多线程同步缺省机制
* @author xiAoT
*
*/
public class Singleton004 {
/**
* 类级内部类
* @author xiAoT
*
*/
private static class SingletonHolder{
private static Singleton004 instance = new Singleton004();
}
private Singleton004(){}
public static Singleton004 getInstance(){
return SingletonHolder.instance;
}
}
类级内部类相当于外部类的成员,只有在第一次使用时才会被加载。
关于反序列化
如果采用了单例的类实现了序列化接口后,在进行反序列时,会自动创建新的类,为了解决这个问题,可以采用readResolve()方法
/**
* 反序列化
*
* @author xiAoT
*
*/
public class Singleton005 implements Serializable {
private Singleton005() {
}
private static final Singleton005 INSTANCE = new Singleton005();
public static Singleton005 getInstance() {
return INSTANCE;
}
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
}
======================================待续===============================
分享到:
相关推荐
设计模式——单例模式源码,设计模式——单例模式源码
设计模式——单例 例子和一些ppt 看下没错的
对应博客讲解:http://blog.csdn.net/t1234xy4/article/details/52419546
单例模式源代码 博文链接:https://yangguangfu.iteye.com/blog/815944
单例的5中实现及反射和反序列化破解单例。
NULL 博文链接:https://794950040.iteye.com/blog/2208104
本篇文章主要介绍了android开发设计模式之——单例模式详解,具有一定的参考价值,有需要的可以了解一下。
单例模式设计。
1)程序功能:单例模式设计Memcache和Redis操作类,采用PHP编写。 2)程序详解地址:http://blog.csdn.net/clevercode/article/details/46410055。 3)原创作品,出自"CleverCode的博客",分类为《设计模式之PHP项目...
今天给大家带来的是23种设计模式的第一种——单例模式。前天写的第一篇文章设计模式的七大原则,是我第一次写文章,目前看了浏览量,让我信心大增。文章有什么讲述方式不对的欢迎大家随时给我私信。24小时恭候!!...
C++设计模式——单例模式-附件资源
我们经常遇到这样的场景,线程A和线程B对同一个对象执行操作,但是在A里面new了后,B里面不便取,使的A,B对象是同一个对象,我们就会使用单例模式了。在Android中我们常用于数据库操作,蓝牙命令控制,以及一些工具...
NULL 博文链接:https://maidoudao.iteye.com/blog/1329564
单例模式的实现饿汉式懒汉式线程安全的懒汉式登记式单例模式的优缺点单例模式的优点单例模式的缺点 单例模式是23个模式中比较简单的模式,应用也非常广泛 什么是单例模式? 单例模式的定义: Ensure a class ...
首先我介绍的是设计模式中比较简单的一个模式——单例模式(因为这里只牵涉到一个类) 二、单例模式的介绍 说到单例模式,大家第一反应应该是——什么是单例模式?,从“单例”字面意思上理解为——一个类只有...
单例模式大家并不陌生,也都知道它分为什么懒汉式、饿汉式之类的。但是你对单例模式的理解足够透彻吗?今天我带大家一起来看看我眼中的单例,可能会跟你的认识有所不同。很容易看出,上面这段代码在多线程的情况下是...
单例模式的介绍 说到单例模式,大家第一反应应该就是——什么是单例模式?...从单例模式的定义中我们可以看出——单例模式的使用自然是当我们的系统中某个对象只需要一个实例的情况,例如:操作系统中只能