在某些场景下为了提高效率,就需要使用多读单写,
这就需要我们使用到GCD中的两个栅栏函数
dispatch_barrier_sync(queue, ^{
//需等待这里的block任务执行完,才能执行后面异步任务
})
dispatch_barrier_async(queue, ^{
//不需要等待block任务执行完,就能执行后面异步任务
})
这两者区别是
1、barrier_sync会阻塞它之后的任务的入队,必须等到 barrier_sync 任务执行完毕,才会把后面的异步任务添加到并发队列中,
2、而 barrier_async不需要等自身的 block 执行完成就可以把后面的任务添加到队列中。
举例:
以读取图片缓存为例来说明:
@property(nonatomic,strong)NSMutableDictionary *imageDic;//假设用于保存图片缓存
@property(nonatomic,strong)dispatch_queue_t concurrent_queue;//并发队列
-(void)initProperties{
//创建一个并发队列
_concurrent_queue = dispatch_queue_create("mutliRead_singleWrite", DISPATCH_QUEUE_CONCURRENT);
//创建字典
_imageDic = [NSMutableDictionary dictionary];
}
//可以多线程进行读
-(UIImage *)getImageWithKey:(NSString *)url{
// __block UIImage *image;
// dispatch_async(self.concurrent_queue, ^{
// image = [self.imageDic valueForKey:url];
// });
UIImage *image;
image = [self.imageDic valueForKey:url];
return image;
}
//只能单线程进行写
-(void)setImageWithKey:(NSString *)key withImg:(UIImage *)image{
dispatch_sync(self.concurrent_queue, ^{
[self.imageDic setValue:image forKey:key];
});
}
//防止多线程同时访问资源,每次只能让一个线程访问进行读写
-(UIImage *)getSafeImage:(NSString *)url{
UIImage *image;
@synchronized (self.imageDic) {
image = [self.imageDic valueForKey:url];
}
return image;
}
-(void)setSafeImageWithKey:(NSString *)key withImg:(UIImage *)image{
@synchronized (self.imageDic) {
[self.imageDic setValue:image forKey:key];
}
}