安全与不安全的单例模式

前几天在android开发中做了一个loginHelper的单例。(不考虑多进程的情况)

在初始化loginHelper单例时。做的一些初始化工作出现了问题。

出问题的初始化工作:

首先随机产生了rsa秘钥对。然后想把这个秘钥对保存在SharedPreference中。

不论android的SharedPreference还是android的NSUserDefaults都是来存储

用户对程序进行的一些偏好设置。在文件系统都是xml文件。

错误表现:

程序保存在xml文件中的秘钥对与程序产生的秘钥对,不吻合。

分析问题:

顿时,我在想为啥在单例模式下还出现了这个问题呢,最后发现,原来我用的

单例模式的方法不是线程安全的。

我用的实现单例的方式:

static LoginHelper  instance = null;

LoginHelper getInstance()

{

  if(instance !=null){

    instance = new LoginHelper();

  }

  return instance;

}

通过上面的方式实现单例是不安全的。由于写文件的时间比较长,很有可能两个线程都会实例化LoginHelper。

后面换了一种方式实现单例模式:

private final static LoginHelper instance = new LoginHelper();

LoginHelper getInstance()

{

  return instance;

}

其实我们也可以通过代码块加锁的形式来防止多线程问题

static LoginHelper  instance = null;

LoginHelper getInstance()

{

  synchronized(this){

    if(instance!=null){

      instance = new LoginHelper();

    }

    return instance;

  }

}

 

由于是final格式的类静态成员,只会在类加载的时候初始化,所以保证instance只会被实例化一次,后面不会被修改。。

其实ios通过gcd技术提供了一种线程安全单例模式实现。

+ (id)sharedInstance
{
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}
posted @ 2013-12-24 13:56  饮识止渴  阅读(368)  评论(0编辑  收藏  举报