zoukankan      html  css  js  c++  java
  • 安全与不安全的单例模式

    前几天在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;
    }
    
  • 相关阅读:
    Mysql语句
    数据库的介绍以及安装
    数据库的基本操作
    进程
    并发编程
    友链
    C/C++第十一届蓝桥杯省赛B组第二场比赛
    数据结构之【栈】+十进制转d进制(堆栈数组模拟)
    sort函数的用法与实验
    memset的实验
  • 原文地址:https://www.cnblogs.com/lzl-sml/p/3488929.html
Copyright © 2011-2022 走看看