dispatch_sync(ConcurrentQueue,^{}) 的疑惑

来源:8-2 dispatch_barrier_async()函数相关面试问题

慕侠2159859

2018-11-25

老师,看你视频说,以同步到并发队列方式才能保证同时有多个线程在读,可是我在我自己写的demo里发现:
for (int j = 0; j<10000; j++) {
dispatch_sync(_queue, ^{
NSLog(@“当前线程为%@=== %d”,[NSThread currentThread],j);
});
}

打印出来的线程都是同一个线程啊,并没有触发出多线程啊?
而上述代码换成dispatch_async 执行打印内容才触发出多线程。那多读岂不是应该用的是dispatch_async(ConcurrentQueue,^{})才对?

或者老师是否再讲述下 线程 和 同步/异步执行,串行/并行队列之间的关系?感觉大多数人都有我这个概念疑惑,谢谢老师!

写回答

1回答

于海

2018-11-25

同步方式栅栏调用会并发执行 指的是在不同的线程里进行同步到并发队列上进行栅栏调用 通过这种方式调用的各个线程间实现并发
你的例子所有同步调用都发生在同一个线程 打印出来的当然是在同一个线程啦

1
3
左耳钉1992
回复
慕粉4084213
其实很简单,提问者的测试代码中,使用同步方式追加任务到并发队列的时候,都是处于同一个线程(就这位同学的代码来看就是主线程),所以,他这里的log都是同一个线程,而栅栏实现多读单写的样例,发生的场景是在不同的线程里调用的`objectForKey`方法中的同步到并发队列的方法,这个时候,是在不同的线程中进行同步到并发队列,其实这个时候,比如说在A线程调用这个读的方法,sync执行任务还是在A线程中执行的,虽然读的操作是被添加到并发队列中的,但是sync执行的任务的执行其实对于这个并发队列也算是串行执行的,但是由于是在不同的线程中调用的这段代码,所以,这种方式只能算是调用的线程之间实现的并发,跟这个并发队列其实没有太大关系。 你可以通过在主线程中添加下面这段代码,来模拟一下在不同的线程中进行读操作: dispatch_queue_t queue = dispatch_queue_create("com.zed.testConcurrentQueue", DISPATCH_QUEUE_CONCURRENT); for (int i = 0; i < 10; i++) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"1 -- i:%d -- thread:%@",i,[NSThread currentThread]); dispatch_sync(queue, ^{ NSLog(@"2 -- i:%d -- thread:%@",i,[NSThread currentThread]); }); }); } } 通过最后的log可以看出,调用读操作的线程与读操作这个任务真正执行的线程是同一个,这样你就能理解了。
2019-04-23
共3条回复

资深大牛带你深度剖析ios高级面试

从BAT/TMD名企真题入手,结合源码及应用,构建完整iOS知识体系

1749 学习 · 600 问题

查看课程