读单例模式自我理解


http://www.runoob.com/design-pattern/singleton-pattern.html


一个单一类,自己负责创建自己,同时确保只有单个对象被创建。提供一个访问其唯一对象的类方法


1. 单例类只能有一个实例。

2. 单例类必须自己创建自己的唯一实例。

3. 单例类必须给所有其他对象提供这一实例


优点:1. 内存中只有一个实例,减少内存开销,尤其是频繁的创建和销毁实例

   2. 避免资源多重占用

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化


懒汉模式:使用方法时才进行创建,需要考虑线程安全问题

饿汉模式:类创建的同时,已经创建好一个静态的对象供使用。是线程安全的

懒汉单例,线程不安全


1.最简单(非线程安全)

+ (PPLAccountManager*)sharedManager {

     if  (sharedInstance == nil ) {     

        sharedInstance = [[self alloc]init];  

    }    

    return sharedInstance;

 }


java类似:

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
}  

    单线程下运行正常,但是在多线程下就有问题了。如果两个线程同时运行到判断shareInstance是否为nil的if语句,且shareInstance没有创建时候,那么2个线程都会创建一个实例,此时单例就不在满足单例模式的要求了。为了保证多线程环境下我们还是只能得到类型的一个实例,需要加上一个同步锁。如下:


2.线程安全(不是最优)

+ (PPLAccountManager*)sharedManager {

     @synchronized ( self ){    

      if (sharedInstance == nil) {            

          sharedInstance = [[selfalloc]init];        

      }        

      return sharedInstance;     

   }

 }


java类似:

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
    public static synchronized Singleton getInstance() {  
    if (instance == null) {  
        instance = new Singleton();  
    }  
    return instance;  
    }  
} 

   这里还不是很完美。我们还是设想两个线程同时想创建一个实例,由于同一时刻只能有一个能得到同步锁,每当第一个线程锁加上锁,第二个线程只能等待,当第一个线程发现实例还没有创建时,它创建一个实例。接着第一个线程释放同步锁,此时第二个线程可以加上同步锁,并运行接下来的 代码。我们每次得到单例实例,都会试图加上一个线程锁,而加锁是一个非常耗时的操作,在没有必要的时候,我们尽量要避免。


3.线程安全(逻辑复杂)

+ (PPLAccountManager*)sharedManager { 

   if (sharedInstance == nil) {      

        @synchronized(self){   

            if (sharedInstance == nil) {      

                sharedInstance = [[self alloc]init];          

            }   

        }   

   }
   return sharedInstance;

 }


public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}  


  这里用了2个if判断来提高效率,但是代码实现逻辑比较复杂,容易出错,我们还有更加优秀的的解法。


4.最优算法(官方推荐)

+ (PPLAccountManager*)sharedManager {


      static dispatch_once_t predicate;   

      dispatch_once(&predicate, ^{        

            sharedInstance = [[self allocinit];    });    

            return sharedInstance; 

      }  

 }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值