在某些場(chǎng)景下為了提高效率,就需要使用多讀單寫,
這就需要我們使用到GCD中的兩個(gè)柵欄函數(shù)
dispatch_barrier_sync(queue, ^{
//需等待這里的block任務(wù)執(zhí)行完,才能執(zhí)行后面異步任務(wù)
})
dispatch_barrier_async(queue, ^{
//不需要等待block任務(wù)執(zhí)行完,就能執(zhí)行后面異步任務(wù)
})
這兩者區(qū)別是
1、barrier_sync會(huì)阻塞它之后的任務(wù)的入隊(duì),必須等到 barrier_sync 任務(wù)執(zhí)行完畢,才會(huì)把后面的異步任務(wù)添加到并發(fā)隊(duì)列中,
2、而 barrier_async不需要等自身的 block 執(zhí)行完成就可以把后面的任務(wù)添加到隊(duì)列中。
舉例:
以讀取圖片緩存為例來說明:
@property(nonatomic,strong)NSMutableDictionary *imageDic;//假設(shè)用于保存圖片緩存
@property(nonatomic,strong)dispatch_queue_t concurrent_queue;//并發(fā)隊(duì)列
-(void)initProperties{
//創(chuàng)建一個(gè)并發(fā)隊(duì)列
_concurrent_queue = dispatch_queue_create("mutliRead_singleWrite", DISPATCH_QUEUE_CONCURRENT);
//創(chuàng)建字典
_imageDic = [NSMutableDictionary dictionary];
}
//可以多線程進(jìn)行讀
-(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;
}
//只能單線程進(jìn)行寫
-(void)setImageWithKey:(NSString *)key withImg:(UIImage *)image{
dispatch_sync(self.concurrent_queue, ^{
[self.imageDic setValue:image forKey:key];
});
}
//防止多線程同時(shí)訪問資源,每次只能讓一個(gè)線程訪問進(jìn)行讀寫
-(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];
}
}