iOS 多线程 同步和异步 串行和并行

    iOS中我们常使用dispatch_queue和NSOperationQueue来实现多线程。而串行和并行、同步和异步,这四个词同时出现的地方是dispatch_queue。NSOperationQueue贴心的隐藏了这些东西,已经不需要我们来操心了。所以下面会使用dispatch_queue来展开。

    线程,线程是程序执行流的最小单元。

    串行队列,后一个任务等待前一任务结束后再执行,按添加顺序一个一个执行。

    并行队列,后一个任务不会等待前一个任务,不等前一个任务完成就会分配新任务。

    串行和并行,这里对应的是队列的概念。队列负责管理多个任务,队列拥有一个线程池,池子里有一个或者多个线程,它按要求将每个任务调度到某一个线程执行。

    抛开同步异步,首先来创建一个队列 dispatch_queue_t ,DISPATCH_QUEUE_SERIAL、DISPATCH_QUEUE_CONCURRENT分别对应串行和并行

    dispatch_queue_t serialQueue = dispatch_queue_create("my.serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

    然后再来说一下dispatch_syncdispatch_async。同步和异步在这里是线程概念,同步不会创建新的线程,会阻塞当前的线程在这个线程里执行任务。而异步则不会阻塞当前线程,会选择在恰当的时机在当前线程或者另开线程执行任务(看系统如何调度),开始任务和完成任务时间是不确定的。
   

在ViewDidLoad里加添加代码run


首先看到viewDidLoad是mainQueue来调度来的任务,而mainQueue是串行的(serial)。

扫描二维码关注公众号,回复: 5602792 查看本文章

这里不能使用dispatch_sync(main,^{});串行队列同步任务中(向同一个串行队列添加同步任务),进行中的任务等待添加任务完成,添加的任务等待上一个任务完成,因为相互等待死循环。在currentQueue中谨慎使用dispatch_sync;

       
2018-07-06 17:04:19.093719+0800 test[23549:749696] 1
2018-07-06 17:04:44.473137+0800 test[23549:749696] 1sync <NSThread: 0x60c000073400>{number = 1, name = main}
2018-07-06 17:04:44.473316+0800 test[23549:749696] 2
2018-07-06 17:04:44.473441+0800 test[23549:749696] 3
2018-07-06 17:05:11.883097+0800 test[23549:749696] 3sync <NSThread: 0x60c000073400>{number = 1, name = main}
2018-07-06 17:05:14.271792+0800 test[23549:749696] 4

因为是同步,任务都被分配到了主线程,同步任务会阻塞当前线程,所以顺序一定是1234。

再把serialQueue换成concurrentQueue,依然用sync同步,得到的结果是1234。同步只会在当前线程(只有一个线程)同时阻塞线程,并行队列失去意义,结果和串行队列一样都是一个一个顺序执行。  

上述代码,我们将sync换成async异步,依然是serialQueue串行队列。得到结果2413、2143、1234串行队列,一个一个执行,那么1肯定在3前面。而异步操作不会阻塞线程,1、3和2、4之间的位置是不确定的;另外补充,串行异步情况下,串行一个一个执行,那么异步分配一个线程就足够了,分配多个线程是没有意义的。

上述代码,换成异步并行


可见因为异步,1、3分别被分配到了线程thread 5、4中执行,(具体分配到哪个线程是不确定的)。

得到结果可能是13,也可能是31,因为是并行队列,不会等待上一个任务完成,异步的执行又是不确定时间的,所以1和3的顺序是不确定的。    


猜你喜欢

转载自blog.csdn.net/wnnvv/article/details/80942156