iOS-线程之GCD方式---之同步异步和串行队列并行队列之间的关系

GCD方式是Apple官方推荐实现多线程的方式

但在这之前必须理清楚同步,异步,串行队列,并行队列之间的概念.

同步:即当前的执行程序块不会创建一个新的线程,只能在当前线程中执行.

异步:会在当前的线程之外创建一个新的线程,并在新的线程中执行代码块.

首先声明一点,队列是用来存放即将执行的线程体的.

串行队列:串行队列中的线程满足FIFO(First In First Out),并且只有在先出的线程执行完,后续的线程才能出队列执行.(很可能造成APP的假死状态)

并行队列:并行队列也满足FIFO,只有利用并行队列和异步的方式配合才能实现多线程同时执行(后面会讲到)

下面的代码部分的四种情况

1.串行队列和同步方式(不推荐使用)

 1 //1.同步方式向串行队列提交代码
 2 //前面的线程执行完成后,才会开始执行后面的线程
 3 - (void)testSyncWithSerialQueue
 4 {
 5     //串行队列
 6     dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
 7     
 8     //线程一
 9     dispatch_sync(serialQueue, ^(void){
10         for (int i=0; i<100; i++) {
11             NSLog(@"线程一:%d",i);
12         }
13     });
14     
15     //线程二
16     dispatch_sync(serialQueue, ^(void){
17         for (int i=0; i<100; i++) {
18             NSLog(@"线程二:%d",i);
19         }
20     });
21 }

执行结果及结论:---前面的线程执行完成后,才会开始执行后面的线程

2015-08-08 19:59:35.730 TestAsyncAndSync[3187:141197] 线程一:96

2015-08-08 19:59:35.730 TestAsyncAndSync[3187:141197] 线程一:97

2015-08-08 19:59:35.731 TestAsyncAndSync[3187:141197] 线程一:98

2015-08-08 19:59:35.731 TestAsyncAndSync[3187:141197] 线程一:99

2015-08-08 19:59:35.731 TestAsyncAndSync[3187:141197] 线程二:0

2015-08-08 19:59:35.731 TestAsyncAndSync[3187:141197] 线程二:1

2015-08-08 19:59:35.731 TestAsyncAndSync[3187:141197] 线程二:2

2015-08-08 19:59:35.731 TestAsyncAndSync[3187:141197] 线程二:3

 

2.串行队列和异步方式

 1 - (void)testAsyncWithSerialQueue
 2 {
 3     dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
 4     //异步,线程一
 5     dispatch_async(serialQueue, ^(void){
 6         for (int i=0; i<100; i++) {
 7             NSLog(@"线程1:%d",i);
 8         }
 9     });
10     
11     //异步:线程二
12     dispatch_async(serialQueue, ^(void){
13         for (int i=0; i<100; i++) {
14             NSLog(@"线程2:%d",i);
15         }
16     });
17 }

执行结果及结论:串行队列前面的线程执行完才能执行后面的线程

2015-08-08 20:03:28.391 TestAsyncAndSync[3225:143307] 线程1:97

2015-08-08 20:03:28.391 TestAsyncAndSync[3225:143307] 线程1:98

2015-08-08 20:03:28.391 TestAsyncAndSync[3225:143307] 线程1:99

2015-08-08 20:03:28.391 TestAsyncAndSync[3225:143307] 线程2:0

2015-08-08 20:03:28.391 TestAsyncAndSync[3225:143307] 线程2:1

2015-08-08 20:03:28.392 TestAsyncAndSync[3225:143307] 线程2:2

 

3.并行队列和同步方式创建线程

 1 - (void)testSyncWithConcurrentQueue
 2 {
 3     dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
 4     //线程一
 5     dispatch_sync(concurrentQueue, ^(void){
 6         for (int i=0; i<100; i++) {
 7             NSLog(@"线程一:%d",i);
 8         }
 9     });
10     
11     //线程一
12     dispatch_sync(concurrentQueue, ^(void){
13         for (int i=0; i<100; i++) {
14             NSLog(@"线程二:%d",i);
15         }
16     });
17 }

结果和结论:先执行线程一,再执行线程二

2015-08-08 20:06:19.111 TestAsyncAndSync[3257:144554] 线程一:97

2015-08-08 20:06:19.111 TestAsyncAndSync[3257:144554] 线程一:98

2015-08-08 20:06:19.111 TestAsyncAndSync[3257:144554] 线程一:99

2015-08-08 20:06:19.112 TestAsyncAndSync[3257:144554] 线程二:0

2015-08-08 20:06:19.112 TestAsyncAndSync[3257:144554] 线程二:1

2015-08-08 20:06:19.112 TestAsyncAndSync[3257:144554] 线程二:2

 

4.并行队列和异步方式

 1 - (void)testAsyncWithConcurrentQueue
 2 {
 3     dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
 4     //异步,线程一
 5     dispatch_async(concurrentQueue, ^(void){
 6         for (int i=0; i<100; i++) {
 7             NSLog(@"线程1:%d",i);
 8         }
 9     });
10     
11     //异步:线程二
12     dispatch_async(concurrentQueue, ^(void){
13         for (int i=0; i<100; i++) {
14             NSLog(@"线程2:%d",i);
15         }
16     });
17     
18 }

执行结果及结论:线程一和线程二同时执行

2015-08-08 20:07:48.318 TestAsyncAndSync[3283:145696] 线程1:0

2015-08-08 20:07:48.318 TestAsyncAndSync[3283:145693] 线程2:0

2015-08-08 20:07:48.319 TestAsyncAndSync[3283:145693] 线程2:1

2015-08-08 20:07:48.319 TestAsyncAndSync[3283:145693] 线程2:2

2015-08-08 20:07:48.319 TestAsyncAndSync[3283:145693] 线程2:3

2015-08-08 20:07:48.319 TestAsyncAndSync[3283:145696] 线程1:1

 

再解释上述的四种情况:不得不说,线程队列是一种神奇的东西,似乎无法控制,又有迹可循...

为什么会造成上面的四种情况呢:

首先来说说第四种情况,异步方式创建线程并使用并行队列存放.主要是因为并行队列允许队列中的线程体出队列后,立马下一个线程体就可以出队列.而使用异步的方式,每一个出来的线程体会创建一个新的线程执行对应的代码块.所以就产生两个线程同时执行的情况.(但是也有让你感到无力的,你无法完全的控制两个线程,即使先出队列线程,也不一定先执行完,线程执行的快慢主要在于两个线程抢占系统资源获得的多少)

第一种和第二种情况:由于串行只允许先进队列的线程,出队列后执行完才能再下一个线程出队列,所以一定是有序(根据进队列的先后)

第三种情况:并行同步方式:虽然并行队列允许多个线程同时出队列(还是先进先出的方式),但是先出的线程不会创建新的线程,只能在当前线程中执行任务,由于当前线程只有一个,所有即使同时出队列多个线程,也只能出于等待.

原文地址:https://www.cnblogs.com/BeyondAverage0908/p/4713826.html