GCD多读单写

在某些场景下为了提高效率,就需要使用多读单写,
这就需要我们使用到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];
    }
}

你可能感兴趣的:(GCD多读单写)