共同点和区别
共同点:分割queue中的任务任务执行
区别: 是否影响主线程代码的执行
- dispatch_barrier_async
NSLog(@"start");
dispatch_queue_t quque = dispatch_queue_create("name", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(quque, ^{
NSLog(@"1");
});
dispatch_async(quque, ^{
NSLog(@"2");
});
dispatch_barrier_async(quque, ^{
NSLog(@"dispatch_barrier_sync");
});
dispatch_async(quque, ^{
NSLog(@"3");
});
dispatch_async(quque, ^{
NSLog(@"4");
});
NSLog(@"end");
2021-12-09 10:42:13.613007+0800 TestOC[2093:1349166] start
2021-12-09 10:42:13.613193+0800 TestOC[2093:1349166] end
2021-12-09 10:42:13.613208+0800 TestOC[2093:1349326] 1
2021-12-09 10:42:13.613223+0800 TestOC[2093:1349327] 2
2021-12-09 10:42:13.613434+0800 TestOC[2093:1349326] dispatch_barrier_sync
2021-12-09 10:42:13.613559+0800 TestOC[2093:1349326] 3
2021-12-09 10:42:13.613568+0800 TestOC[2093:1349327] 4
- dispatch_barrier_sync
NSLog(@"start");
dispatch_queue_t quque = dispatch_queue_create("name", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(quque, ^{
NSLog(@"1");
});
dispatch_async(quque, ^{
NSLog(@"2");
});
dispatch_barrier_sync(quque, ^{
NSLog(@"dispatch_barrier_sync");
});
dispatch_async(quque, ^{
NSLog(@"3");
});
dispatch_async(quque, ^{
NSLog(@"4");
});
NSLog(@"end");
start
2021-12-09 10:43:14.680469+0800 TestOC[2122:1350990] 1
2021-12-09 10:43:14.680495+0800 TestOC[2122:1350986] 2
2021-12-09 10:43:14.680703+0800 TestOC[2122:1350823] dispatch_barrier_sync
2021-12-09 10:43:14.680835+0800 TestOC[2122:1350823] end
2021-12-09 10:43:14.680849+0800 TestOC[2122:1350986] 3
2021-12-09 10:43:14.680853+0800 TestOC[2122:1350990] 4
结论:dispatch_barrier_sync会阻塞主线程任务的执行
注: 栅栏函数用用自定义的并发队列才有意义
- 尽量使用自定义的并发队列:
使用全局队列
起不到栅栏函数的作用
使用全局队列
时由于对全局队列造成堵塞,可能致使系统其他调用全局队列的地方也堵塞从而导致崩溃(并不是只有你在使用这个队列)
- 栅栏函数只能控制同一并发队列:打个比方,平时在使用
AFNetworking
做网络请求时为什么不能用栅栏函数起到同步锁堵塞的效果,因为AFNetworking
内部有自己的队列
实现读写锁(多读单写)
@interface ViewController ()
@property (nonatomic, strong) dispatch_queue_t rwqueue;
@property (nonatomic, assign) NSInteger tickets;
@end
@implementation ViewController
//初始化 异步队列
self.rwqueue = dispatch_queue_create("rw.thread", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
for (NSInteger i = 0; i < 30; i ++) {
dispatch_async(queue, ^{
[self readBarryier];
[self readBarryier];
[self writeBarrier];
[self readBarryier];
});
}
}
- (void)readBarryier{
//添加任务到rwqueue
dispatch_async(self.rwqueue, ^{
NSLog(@"读文件 %@ - %ld",[NSThread currentThread], self.tickets);
sleep(1);
});
}
- (void)writeBarrier{
//barrier_async添加任务到self.rwqueue中
dispatch_barrier_async(self.rwqueue, ^{
self.tickets++;
NSLog(@"写入文件 %@ - %ld",[NSThread currentThread], self.tickets);
sleep(1);
});
}
@end
- (id)readDataForKey:(NSString*)key {
__block id result;
dispatch_sync(_concurrentQueue, ^{
result = [self valueForKey:key];
});
return result;
}
- (void)writeData:(id)data forKey:(NSString*)key {
dispatch_barrier_async(_concurrentQueue, ^{
[self setValue:data forKey:key];
});
}
- 读:并发异步
获取到值后返回给读者
- 若使用
并发异步
则会先返回空的result 0x0
,再通过getter方法获取到值- 写:写的那个时间段,不能有任何读者+其他写者
dispatch_barrier_async
满足:等队列中前面的读写任务都执行完了再来执行当前任务
网友评论