先来看栅栏函数 dispatch_barrier_sync 和dispatch_barrier_async 1.dispatch_barrier:是一个拦截函数. 2.dispatch_barrier:要想拦截成功必须站在一条路上,也就是位于同一线程.
下面来看第一个:dispatch_barrier_sync 代码:
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue2 = dispatch_queue_create("myQueue2", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
//任务1
for (int i = 0; i < 5; i++) {
NSLog(@"任务一、来自线程:%@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
//任务1
for (int i = 0; i < 5; i++) {
NSLog(@"任务二、来自线程:%@",[NSThread currentThread]);
}
});
dispatch_barrier_sync(queue, ^{
//栅栏
for (int i = 0; i < 1 ; i++) {
NSLog(@"任务拦截、来自线程:%@",[NSThread currentThread]);
}
});
NSLog(@"任务xxxxxx路人甲");
dispatch_async(queue, ^{
//任务1
for (int i = 0; i < 2; i++) {
NSLog(@"任务三、来自线程:%@",[NSThread currentThread]);
}
});
输出入结果
这里注意:路人甲的 和任务三的执行顺序.
再来看一下dispatch_barrier_async输出:
区别:
路人甲 在dispatch_barrier_sync下是要等栅栏函数执行完成才执行 而在dispatch_barrier_async下是先执行的 任务三 无论都在栅栏函数之后执行的
这以上就是栅栏函数的同步和异步的区别.
理解了上面我们再来看使用dispatch_barrier来实现多读单写: 多读单写的定义:
- 读并发执行,写同步执行
- 读和写是互斥的,读是需要等待结果返回的
- 写之前要等所有读操作完成之后开始,写不用等结果
上面的条件要求中: 1."写之前要等所有读操作完成之后开始":这个就是栅栏函数,"不用等结果":async 2."读并发执行":就是并发队列,"读要等结果":就是同步sync 3.栅栏函数起作用的条件就是在同一线程
所以多读单写的实现如下:
#import "SXReadWriteSafeDic.h"
@interface SXReadWriteSafeDic ()
{
// 定义一个并发队列
dispatch_queue_t concurrent_queue;
// 用户数据中心, 可能多个线程需要数据访问
NSMutableDictionary *userCenterDic;
}
@end
@implementation SXReadWriteSafeDic
- (instancetype)init
{
self = [super init];
if (self) {
concurrent_queue = dispatch_queue_create("readWriteSafeQ", DISPATCH_QUEUE_CONCURRENT);
userCenterDic = [NSMutableDictionary dictionary];
}
return self;
}
///:读要求:
///1. 读操作要等结果:sync
///2.要和写操作互斥:在同一线程
///3.多读:concurrent_queue 并发线程
- (id)objecForKey:(NSString *)key {
__block id obj;
dispatch_sync(concurrent_queue, ^{
obj = userCenterDic[key];
});
return obj;
}
///写要求:
/// 1.和读互斥:栅栏函数
///2.等所有读操作完成之后
///3.写操作不用等待结果:async
- (void)setObejct:(id)obj forKey:(NSString *)key {
dispatch_barrier_async(concurrent_queue, ^{
[self->userCenterDic setObject:obj forKey:key];
});
}
加深理解,如有问题欢迎指正.