同步和异步决定了要不要开启新的线程
同步(sync):在当前线程中执行任务,不具备开启新线程的能力
异步(async):在新的线程中执行任务,具备开启新线程的能力
并发和串行决定了任务的执行方式
并发:多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务
关于同步异步串行并行的执行顺序,做如下实验:
1 全局队列异步执行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
});
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
执行结果:1 4 2 3
解释:1先打印 23异步执行,在新的线程,不管有没有打印,直接执行4
执行了好几次,一直是这个结果,难道这是必然的吗?
4一定在23前面吗?
对代码做如下处理:对4加上一个300的打印循环
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"22");
});
dispatch_async(queue, ^{
NSLog(@"333");
});
for(int i = 0; i<300; i++)
{
NSLog(@"4");
}
多次运行出现如下结果:
2018-08-22 18:18:45.808029+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.808226+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.808276+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.774753+0800 Test2018[2149:1050723] 22
2018-08-22 18:18:45.811065+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.774814+0800 Test2018[2149:1050788] 333
2018-08-22 18:18:45.811114+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.811191+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.811245+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.811298+0800 Test2018[2149:1050563] 4
说明,23异步执行,不一定非要在最后才执行,不过,异步执行需要时间,因此,一般情况是慢于主线程的打印操作
2一定在3前面吗?
同样,对2做300次的打印循环:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
for(int i = 0; i<300; i++)
{
NSLog(@"22");
}
});
dispatch_async(queue, ^{
NSLog(@"333");
});
NSLog(@"4");
```
出现以下结果:
```c
2018-08-22 18:25:26.215547+0800 Test2018[2154:1051708] 22
2018-08-22 18:25:26.215586+0800 Test2018[2154:1051708] 22
2018-08-22 18:25:26.205837+0800 Test2018[2154:1051712] 333
2018-08-22 18:25:26.218334+0800 Test2018[2154:1051708] 22
2018-08-22 18:25:26.218402+0800 Test2018[2154:1051708] 22
说明,并不是2执行完才执行3
以上说明,只针对题的话,打印是1423。但是,如果抛开题的话,1是先执行,23交替执行,一般是先执行2再执行3,4是在主线程,比子线程打印快,因此,4比23先打印,但是并不是4打印完之后才执行23,是4比较快而已,23子线程比较慢
1打印 4是主线程,23是子线程,因此,4比23先开始。2比3先开始
2 全局队列同步执行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_sync(queue, ^{
NSLog(@"2");
});
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
执行结果:1 2 3 4
解释:1先打印 23同步执行,不开启新的线程,所以,只能顺序执行:1234
3 全局队列一同步一异步执行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2---%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3---%@",[NSThread currentThread]);
});
NSLog(@"4");
执行结果:1 3 4 2
2018-08-22 17:56:27.046521+0800 Test2018[2127:1046667] 1
2018-08-22 17:56:27.047417+0800 Test2018[2127:1046667] 3---<NSThread: 0x17007a5c0>{number = 1, name = main}
2018-08-22 17:56:27.047518+0800 Test2018[2127:1046667] 4
2018-08-22 17:56:27.048704+0800 Test2018[2127:1046686] 2---<NSThread: 0x17426c380>{number = 3, name = (null)}
解释:1先打印 3因为是同步,所以34顺序执行,2是子线程,所以耗时,在最后执行
4 全局队列一异步一同步执行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_sync(queue, ^{
NSLog(@"2");
});
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
执行结果:1 2 4 3
解释:1先打印 2因为是同步,所以顺序执行2,3是异步线程,耗时,因此在最后
5 串行队列异步执行
dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
});
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
执行结果:1 4 2 3
对于1先打印没有异议,但4一定在2和3的前面吗?一定是4执行完之后,才执行2和3吗?2一定在3的前面吗?
为4增加300个循环
dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2-%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3-%@", [NSThread currentThread]);
});
for (int i = 0; i<300; i++) {
NSLog(@"4-%@", [NSThread currentThread]);
}
结果如下:
2018-10-18 13:41:43.992993+0800 test001[2284:162778] 1
2018-10-18 13:41:43.993228+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}
2018-10-18 13:41:43.993252+0800 test001[2284:162835] 2-<NSThread: 0x60400027a580>{number = 3, name = (null)}
2018-10-18 13:41:43.993364+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}
2018-10-18 13:41:43.993383+0800 test001[2284:162835] 3-<NSThread: 0x60400027a580>{number = 3, name = (null)}
2018-10-18 13:41:43.993497+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}
2018-10-18 13:41:43.993645+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}
4是同步,比异步2、3快,但并不是4执行完毕后才执行2和3;2和3是异步执行,具有开启新线程的能力,在开启新的线程后,CPU在线程中切换执行,因此会出现1424344这样的结果。
更进一步:
对上述代码添加多行打印:
dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
for (int i = 0; i<10; i++) {
NSLog(@"2-%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i<10; i++) {
NSLog(@"3-%@", [NSThread currentThread]);
}
});
for (int i = 0; i<30; i++) {
NSLog(@"4-%@", [NSThread currentThread]);
}
打印结果如下:
2018-10-18 13:47:42.759085+0800 test001[2363:167342] 1
2018-10-18 13:47:42.759324+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.759352+0800 test001[2363:167390] 2-<NSThread: 0x60400046c880>{number = 3, name = (null)}
2018-10-18 13:47:42.759529+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.759758+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.759763+0800 test001[2363:167390] 2-<NSThread: 0x60400046c880>{number = 3, name = (null)}
2018-10-18 13:47:42.760094+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.760178+0800 test001[2363:167390] 2-<NSThread: 0x60400046c880>{number = 3, name = (null)}
可以看出,CUP是在多个线程(2、4)中切换打印的。
那么,一定在3前面吗?
dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
for (int i = 0; i<50; i++) {
NSLog(@"2-%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i<50; i++) {
NSLog(@"3-%@", [NSThread currentThread]);
}
});
NSLog(@"4");
NSLog(@"4-%@", [NSThread currentThread]);
结果如下:
2018-10-18 13:53:08.622294+0800 test001[2445:171837] 1
2018-10-18 13:53:08.622439+0800 test001[2445:171837] 4
2018-10-18 13:53:08.622512+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.622685+0800 test001[2445:171837] 4-<NSThread: 0x604000069600>{number = 1, name = main}
2018-10-18 13:53:08.622699+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.623103+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
...(全是2省略)
2018-10-18 13:53:08.648776+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.648984+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.650128+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652104+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652411+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652596+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652757+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652907+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.653042+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.653188+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.653386+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
可以看出,2一定会在3前面,即2执行完毕后,才执行3。
异步串行,会开启新的线程,但是只会开启一条,而且是顺序串行。因此,2执行完毕后才执行3。
总结:异步串行,只会开启一条线程。2、3顺序确定,2一定在3前面。但是2、4以及3、4这种子线程和主线程之间,CPU可以切换执行
6 串行队列同步执行
dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_sync(queue, ^{
NSLog(@"2");
});
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
执行结果:1 2 3 4
解释:1先打印;因为是串行,一个接一个的执行,因为是同步,所以不具备开启新线程的能力,所以会顺序执行。
7 串行队列一异步一同步执行
dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
});
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
执行结果:1 2 3 4
解释:
8 串行队列一同步一异步执行
dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_sync(queue, ^{
NSLog(@"2");
});
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
执行结果:1 2 3 4
解释: