今天在写一个东西需要用的单例模式,一般的单列模式可分为以下两种:
1 饿汉式:
public class Singleton{
private static Singleton singleton = new Singleton ();
private Singleton (){}
public Singleton getInstance(){return singletion;}
}
2 懒汉式:
public class Singleton{
private static Singleton singleton = null;
public static Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
安全分析:
1 从线程角度:
从线程角度看,我们会发现,饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变,懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的,所以在使用懒汉式时我们的考虑到线程安全问题
改进后的懒汉式:
public class Singleton{
private static Singleton singleton = null;
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
2 从安全角度:
ok,线程安全我们解决了,但是对于有些对系统的安全要求再高些的那,比如:操作系统的权限,
提醒下,在享有特权的客户可以借助AccessibleObject.setAccessible方法,通过反射机制来调用你的私有构造器。如果你的系统需要的安全级别比较高的话,为了抵御这用攻击,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。
3 从序列化角度:
我有时候会用到序列化,那怎样保证单例模式的安全?难道就仅仅在声明中加上”implements Serializable“就可以?这不够的,为了保证单列,我们还得声明所有实例域都是瞬时的,并提供一个readResolve方法,否则我们每次反序列化一个序列化的实例时,都会创建一个新实例,针对需要序列化的,我们可以加上这个方法:
private Object readResolve(){
return singleton;
}
这只是我所想到和看到的,当然有不足之处还请大家多指教!
1 饿汉式:
public class Singleton{
private static Singleton singleton = new Singleton ();
private Singleton (){}
public Singleton getInstance(){return singletion;}
}
2 懒汉式:
public class Singleton{
private static Singleton singleton = null;
public static Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
安全分析:
1 从线程角度:
从线程角度看,我们会发现,饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变,懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的,所以在使用懒汉式时我们的考虑到线程安全问题
改进后的懒汉式:
public class Singleton{
private static Singleton singleton = null;
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
2 从安全角度:
ok,线程安全我们解决了,但是对于有些对系统的安全要求再高些的那,比如:操作系统的权限,
提醒下,在享有特权的客户可以借助AccessibleObject.setAccessible方法,通过反射机制来调用你的私有构造器。如果你的系统需要的安全级别比较高的话,为了抵御这用攻击,可以修改构造器,让它在被要求创建第二个实例的时候抛出异常。
3 从序列化角度:
我有时候会用到序列化,那怎样保证单例模式的安全?难道就仅仅在声明中加上”implements Serializable“就可以?这不够的,为了保证单列,我们还得声明所有实例域都是瞬时的,并提供一个readResolve方法,否则我们每次反序列化一个序列化的实例时,都会创建一个新实例,针对需要序列化的,我们可以加上这个方法:
private Object readResolve(){
return singleton;
}
这只是我所想到和看到的,当然有不足之处还请大家多指教!