美文网首页
@synchronized和dispatch_once的区别

@synchronized和dispatch_once的区别

作者: 编程_书恨少 | 来源:发表于2018-11-28 20:40 被阅读0次

    时间:2018-11-28

    今天在项目中看到了

    static FuDaoManager * __instance__ = nil;
    
    + (instancetype)sharedInstance {
        @synchronized (__instance__) {
            if (!__instance__) {
                __instance__ = [[self alloc] init];
                [__instance__ loadData];
            }
        }
        return __instance__;
    }
    

    这种单例的创建方式,以前没有这么写过,因为从直觉上觉得@synchronized 是需要加锁的,这是需要消耗性能的,应该是使用diapatch_once吧,但是项目中确实是这么写的。本着不能靠揣测的原则,查阅相关资料进行学习才是最有效的学习方式,于是找到了一篇博客,这里直接上结论,有兴趣的同学可以直接进入学习。

    性能差异

    上面的这些写法大家应该都很熟悉,既然两种方式都能实现,我们来看看两者的性能差异,这里简单写了个测试的demo,使用两个方法分单线程跟多线程(采用dispatch_apply方式,性能相对较高)去访问一个单例对象一百万次,对比这期间的耗时,从iPod跟5s测试得到如下的结果

    //ipod,主线程
        SingletonTest[4285:446820] synchronized time cost:2.202945s
        SingletonTest[4285:446820] dispatch_once time cost:0.761034s
        
        //5s,主线程
        SingletonTest[5372:2394430] synchronized time cost:0.466293s
        SingletonTest[5372:2394430] dispatch_once time cost:0.070822s
    
        //ipod,多线程
        SingletonTest[4315:448499] synchronized time cost:3.385109s
        SingletonTest[4315:448499] dispatch_once time cost:0.908009s
        
        //5s,多线程
        SingletonTest[5391:2399069] synchronized time cost:0.507504s
        SingletonTest[5391:2399069] dispatch_once time cost:0.169934s
    

    总结

    通过上面的分析,我们知道@synchronized采用的是递归互斥锁来实现线程安全,而dispatch_once的内部则使用了很多原子操作来替代锁,以及通过信号量来实现线程同步,而且有很多针对处理器优化的地方,甚至在if判断语句上也做了优化(逼格有点高),使得其效率有很大的提升,虽然其源码很短,但里面包含的东西却很多,所以苹果也推荐使用dispatch_once来创建单例。通过这个简短的dispatch_once,你也可以清楚为什么GCD的性能会这么高了,感兴趣可以再去看看libdispatch的其它源码。

    具体博文链接放在这https://www.jianshu.com/p/ef3f77c8b320

    相关文章

      网友评论

          本文标题:@synchronized和dispatch_once的区别

          本文链接:https://www.haomeiwen.com/subject/lfttcqtx.html