大话设计模式--第21章 有些类也需要计划生育--单例模式

21 有些类也需要计划生育--单例模式


21.3 生还是不生是自己的责任

21.4 单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。


通常我们可以设置一个全局变量使得这一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。


21.5 多线程时的单例

lock是确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其它线程试图进入锁定的代码,则他将一直等待(即被阻塞),知道该对象被释放。


class Singleton

{

    private static Singleton instance;

    private static readonly object syncRoot = new object();

    private Singleton()

    {

    }


    public static Singleton GetInstance()

    {

        if(instance == null)        //1 非空判断

        {

            lock(syncRoot)

            {

                if(instance == null)    //2 非空判断

                {

                    instance = new Singleton();

                }

            }

        }

        return instance;

    }

}


注意看此处有两个非空判断:

如两个线程,两个线程可能同时通过判断1,若线程1先通过,线程1通过后实例化了对象,然后你会发现如果没有判断2,线程2也会实例化一个对象,这就不是单例了。


IOS单例模式:

1:使用dispatch_once_t;


+ (AccountManager *)sharedManager { 

    static AccountManager *sharedAccountManagerInstance = nil; 


    static dispatch_once_t predicate; dispatch_once(&predicate, ^{       

          sharedAccountManagerInstance = [[self alloc] init]; 

    });


    return sharedAccountManagerInstance; 


}



2:使用@synchronized


+ (id)sharedInstance

{

    static Instance *obj = nil;

    @synchronized([Instance class])

    {

        if(!obj)

            obj = [[Instance alloc] init];

    }

    return obj;

}




    static dispatch_once_t once;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"------0");

        [NSThread sleepForTimeInterval:1.0];

        NSLog(@"------1");

        dispatch_once(&once, ^{

            NSLog(@"------2");

        });

        NSLog(@"------3");

    });

    

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"------4");

        dispatch_once(&once, ^{

            NSLog(@"------5");

            [NSThread sleepForTimeInterval:2.0];

            NSLog(@"------6");

        });

        NSLog(@"------7");

    });

    /* 40/04 5 1 6 37/73

     2016-06-29 18:36:43.501 GCD[1679:122152] ------4

     2016-06-29 18:36:43.501 GCD[1679:122153] ------0

     2016-06-29 18:36:43.502 GCD[1679:122152] ------5

     2016-06-29 18:36:44.504 GCD[1679:122153] ------1

     2016-06-29 18:36:45.504 GCD[1679:122152] ------6

     2016-06-29 18:36:45.505 GCD[1679:122152] ------7

     2016-06-29 18:36:45.505 GCD[1679:122153] ------3

     */



dispatch_once不仅仅保证临界区域的代码只执行一遍,还可以保证多个线程同时到达临界区域时,只有一个线程可以进入,其它会被阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值