第41条:多用派发队列,少用同步锁
1.错误的线程安全的存取方法
-(NSString*)someString{
@synchronized(self){ return _someString;}
}
通过同步块synchronized来设计存取方法是不正确的,所有同步块都要去抢夺同一个锁,如果每个属性都这样写的话,那个每个属性的同步块都要等其它属性的同步块执行完了才能执行,这样效率很低。而且这样也不能做到真正的线程安全,在同一个线程上多次调用getter方法,得到的值可能是不同的,因为在两次方法的执行期间可能有其它线程执行了setter操作。
2.用gcd实现线程安全的存取方法
思路:把gcd的存取操作都放到同一个队列中执行,那么在这个队列只要保证了存取方法的线程安全,就保证了整个线程的安全。
为了加快效率,我们发现多个读取方法可以并发执行,但是写入操作必须单独执行。因此我们可以开启一个并发队列,同时用栅栏函数,在并发队列里,栅栏块必须单独执行,不能和其它任务块并行。
getter方法
-(NSString*)someString{
__block NSString* localSomeString;
[dispatch_sync(dispatch_get_global_queue(0, 0), ^{
localSomeString = _someString;
})];
return localSomeString;
}
setter方法
-(void)setSomeString:(NSString*)someString{
dispatch_barrier_async(dispatch_get_global_queue(0, 0), ^{
_someString = someString;
});
}
网友评论