篇幅有点长,持续补充中。
首先我们要明白一个东西,队列是队列,线程是线程,在队列里执行代码,可能会创建新的线程,下面我们通过几种case,来说明常见的一些情况.一切以实际测试情况为准.
1. 串行队列,同步执行
case1.
从主线程,开始执行,结果是不会创建新的线程,顺序执行,由此可以推测,在另外一个线程里面,也只这样,不会创建线程,在当前线程,顺序执行.我们再测试另外一种case,从不同的线程,进入一个同步队列,串行执行,结果会怎样呢?
case2.
上诉结果说明两个事实:
1. 并不是111,222,333,444,555,666 这样执行的,为什么,因为是通过global async 加进去的,并行加入的顺序,不一定是123456,所以执行的顺序是,加入的顺序,这里是 134256
2. 执行的线程,是从global 加入线程里执行的,这里很明显就表示,线程是线程,队列是队列,不管你从哪个线程加入的,在串行队列里,就是那个先来,就执行那个.
2. 串行队列,并发执行
case3. 代码如下:
以上结果说明,串行队列,并行执行,结果无非是新开了一个线程,再在这个新的线程里面串行执行。
case4.
与case2 基本一致,谁先来,谁先进入队列去排队,就好比从10条车道上来了10辆车,进入一个加油站,加完油,选择同一条路(同一个线程,这个线程是随机分配的,但是一定是同一条)出去,车子谁先来,就谁先进加油站。但是看打印发现一个问题,车子来的顺序是 1230546789,车子出去的顺序是 1230564789,6和4顺序反了,这是什么情况,经过多次测试,发现,大部分情况是一致的,我的猜测是,打印的顺序与车子实际到达加油站的顺序是有误差的,也就是,6 实际比4线到达,但是4 比6 先报备,至于怎么解决这个误差,以后再研究。
总之,同步队列,就是谁先到谁先执行。dispath_async 只不过是开辟一个新的线程,去串行执行而已,dispath_sync ,则就是添加任务的线程,串行去执行。
diapathch_async(global,{ })的方式去给同步队列添加任务,结果还是,谁先添加进来,谁先执行,只不过添加进来的任务顺序随机罢了,如case2,case4.
3. 并行队列,串行执行
case5.
结果和case1 一样,所以在这种case下,和case1是一摸一样的(其实内部肯定有不一样,后面会有case说明),相当于,一个加油站,可以允许很多辆车同时进来,但是你就一条道,挨个进来,那我只能挨个出去了
case 6. 并行队列,串行执行,但是,是并行加入任务的
打印结果,执行thread=== 的顺序是 0231567849,执行 thread i 的顺序是2031564879,这任务4 也延后太多了吧,也就是任务4很早就加入了,但是很晚才执行,说明什么,说明,dispatch_sync(queue,^{ });里面执行的任务,没有相互等待,也就是,这个queue ,是并行的队列,即使是sync 执行,sync 表示在加入他们的地方,是串行执行的,也就是,NSLog(@"thread=== %d:%@",i,[NSThread currentThread]); 和 他紧挨着的 dispatch_sync(queue,^{ });任务是串行执行的,而不同的dispatch_sync(queue,^{ }); 之间并没有相互等待,就好比,10辆车,先后进加油站,进了之后各自加油,然后各自出去,并不是一辆车加完油出去了,另外一辆车才能进来加油,怎么证明我的说法呢,看他们是否相互等待就行了,看以下代码:
0 并没有等待1 执行完之后再执行,其实这种写法的执行效果,和下面这种写法是一个道理,只不过把任务加入到queue里面执行罢了:
那既然这样,那加入到queue 还有什么意义呢,有!比如我们一个数据,很多线程都在读和写,如果只控制写的地方,比如对写的地方加锁,还是有问题,什么问题呢,加锁只是对 写的代码块儿加锁,也就是,写是串行的了,但是写的同时其他线程还有可能在读啊,也就是本来这一刻我应该读的是数据时1,你同时还在操作这个指针,让他指向2,那么我读出来的该是1 还是2呢。而加入队列的话,可以解决这个问题,写的时候,加入队列栏杆(iOS 上叫dispatch_barrier_async),这样写的时候,读全部停下来,写完之后,你再继续,这样就不会读写冲突了。上面的代码还可以验证case4 ,证明case4结论是正确的.
case7 . 并行队列,async 执行
这种case,就很好理解了,各自进,各自出,不想关,线程有queue 自己分配,可能在一个,也可能不是一个.这种case,理解为,一个车道上进入加油站,有很多油箱,一个一个的进加油站,但是自己加完自己走,走的道也有很多条,谁先走,看谁先加完。
case8 . 并行队列,async 执行,而且加入的时候,都是不同的线程加的。
这种case 也很好理解,场景也很普通,不同的线程,async 一个并行队列,去做一些事,如果需要控制这些事之间的依赖关系,可以加group 或者dispatch_barrier_async来控制。这就好比,很多个车道,车辆先后进入,加油站有很多加油位,自己加完,自己走。
以上8中case ,基本整理完,并行、串行、async、sync 各种执行case,下面再来说一种case ,死锁。
case9.
第一种死锁,串行队列,串行执行
这个很好理解,串行队列里,事件1 等待事件2完成,事件2等待事件1完成,相互等待,死锁
case 10.
串行队列,async 执行,代码如下:
相当于,新开了一个线程,在这个线程里面,相互等待,死锁
case 11.
这种情况下,没有死锁,为什么,queue 执行事件1, 过程中,新开了一个线程,把线程里面的任务2,异步加入到队里里面,任务1 执行完之后,在异步的执行任务2,没有问题。
case12. 并发队列,但是同步执行
理论上,并行队列,但是队列里面的任务还是同步执行,应该相互等待,然而结果不是,打印结果是打印完 j 再打印k,说明什么,说明,并行队列,执行过程中,串行的加入任务,这个任务居然插队了,不用等待前一个任务完成就执行,很神奇,可能是 并行队列做了处理,我也希望有人给我解惑啊,将第一个diapath_async 换成 dispath_sync 结果一样,只是换到主线程执行而已!!!
大致就是这样了,如果遇到新发现,我会及时更新的 !