本篇博客转载自: 点击打开链接 http://www.cnblogs.com/fernandolee24/p/5366720.html
public class LazySignleton {
private volatile static LazySignleton INSTANCE = null;
private LazySignleton(){ }
pbulic static synchronized LazySignleton getInstance(){
if(INSTANCE == null)
INSTANCE = new LazySignleton();
return INSTANCE;
}
}
3、懒汉式的改进
当然既然懒汉式有这个缺点,我们可以单独对其处理,如果实例已经创建过了,就不需要进行加锁了,如下是改良后的实例方式:
public static LazySignleton getInstance(){
if(INSTANCE == null){
synchronized(LazySignleton.class){
if(INSTANCE == null){
INSTANCE = new LazySignleton();
}
}
}
return INSTANCE;
}
public
class
SafeSingleton
implements
Serializable, Cloneable {
private
static
final
long
serialVersionUID = -4147288492005226212L;
private
static
SafeSingleton INSTANCE =
new
SafeSingleton();
private
SafeSingleton() {
if
(INSTANCE !=
null
) {
throw
new
IllegalStateException(
"Singleton instance Already created."
);
}
}
public
static
SafeSingleton getInstance() {
return
INSTANCE;
}
private
Object readResolve()
throws
ObjectStreamException {
return
INSTANCE;
}
public
Object clone()
throws
CloneNotSupportedException {
throw
new
CloneNotSupportedException(
"Singleton can't be cloned"
);
}
}
|
在原有Singleton的基础上完善若干方法即可实现一个安全的更为纯正的Singleton。注意到当实例已经存在时试图通过调用私有构造函数会直接报错从而抵御了反射机制的入侵; 让调用clone方法直接报错避免了实例被克隆;覆写readReslove方法直接返回现有的实例本身可以防止反序列化过程中生成新的实例。而对于不同类加载器导致的单例模式破坏暂未找到切实可行的应对方案,请大牛提供高见。
2、Enum Signleton
public
enum
EnumSingleton{
INSTANCE;
private
EnumSingleton(){
}
}
|
采用枚举的方式实现Singleton非常简易,而且可直接通过EnumSingleton.INSTANCE获取该实例。Java中所有定义为enum的类内部都继承了Enum类,而Enum具备的特性包括类加载是静态的来保证线程安全,而且其中的clone方法是final的且直接抛出CloneNotSupportedException异常因而不允许拷贝,同时与生俱来的序列化机制也是直接由JVM掌控的并不会创建出新的实例,此外Enum不能被显式实例化反射破坏也不起作用。当然它也不是没有缺点,比如由于已经隐式继承Enum所以无法再继承其他类了(Java的单继承模式限制),而且相信大多数人并不乐意仅仅为了实现一个纯正的Singleton就将习惯的class修改为enum。
本文详细介绍了单例模式的四种实现方式,包括饿汉式、懒汉式及其改进版、静态内部类实现。同时探讨了如何破坏单例模式,并提出了两个真正安全的单例实现方案:SafeSingleton和EnumSingleton。
774

被折叠的 条评论
为什么被折叠?



