转载请注明出处
http://blog.csdn.net/guodongAndroid/article/details/52032750
本文来自【孫小逗的博客】
一、概述
Singleton模式是在编程实践中应用最广泛的几种设计模式之一。以前常用的是下面的这种方法:
public class Singleton
{
private volatile static Singleton instance;
private Singleton(){};
public static Singleton getInstance()
{
if (instance == null)
{
synchronized (Singleton.class)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
}
这种方法称为双重校验锁,极不推荐使用。
二、其他实现Singleton的方法
1、饿汉式:
public class Singleton
{
public static final Singleton INSTANCE = new Singleton();
private Singleton(){};
}
2、饿汉式变种(1)
public class Singleton
{
private static final Singleton INSTANCE = new Singleton();
private Singleton(){};
public static Singleton getInstance()
{
return INSTANCE;
}
}
这两种方式都要求使用私有构造器,私有构造器仅被调用一次,用来实例化静态final域Singleton.INSTANCE。
3、饿汉式变种(2) 类初始化的时候实例化instance
public class Singleton
{
private static Singleton instance = null;
private Singleton(){};
static
{
instance = new Singleton();
}
public static Singleton getInstance()
{
return instance;
}
}
4、静态内部类
public class Singleton
{
private static class SingletonHolder
{
private static final Singleton instance = new Singleton();
}
private Singleton(){};
public static Singleton getInstance()
{
return SingletonHolder.instance;
}
}
这四种方法都可以借助AccessibleObject.setAccessible方法,通过反射机制,调用私有构造器创建新的实例,如下图:
可见s1 == s2为fasle,说明创建了两个实例,也用失去了Singleton属性。如果需要抵御这种攻击,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。
三、使用单元素的枚举实现Singleton
public enum Singleton
{
INSTANCE;
public void dosomething()
{
System.out.println(this + " is speaking!");
}
}
先看下运行后的结果:
使用单元素的枚举类型实现Singleton时,通过反射机制去创建新的实例时会抛出异常。
和以前的s1 == s2对比,可以看到使用单元素的枚举类型在功能上与公有域方法相近,但是它更加简洁,并且无偿得提供了序列化机制,绝对防止多次实例化。