`
石头的日记
  • 浏览: 199093 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类

你的单例模式安全吗

阅读更多

今天在写一个东西需要用的单例模式,一般的单列模式可分为以下两种:

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
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics