iOS GCD (一) 任務(wù)+隊(duì)列 基礎(chǔ)組合
iOS GCD (二 ) dispatch_group 隊(duì)列組
iOS GCD(三) dispatch_barrier_async 柵欄方法
iOS GCD (四) dispatch_semaphore 信號量
iOS GCD(五) 死鎖案例分析
iOS GCD(六)線程加鎖
隊(duì)列分為串行于并行 任務(wù)分同步和異步 主隊(duì)列特殊隊(duì)列
由此 我們可以得出以下6種組合方式
1.同步執(zhí)行 + 并發(fā)隊(duì)列
2.異步執(zhí)行 + 并發(fā)隊(duì)列
3.同步執(zhí)行 + 串行隊(duì)列
4.異步執(zhí)行 + 串行隊(duì)列
5.同步執(zhí)行 + 主隊(duì)列
6.異步執(zhí)行 + 主隊(duì)列
1 同步執(zhí)行 + 并發(fā)隊(duì)列
在當(dāng)前線程中執(zhí)行任務(wù),不會開啟新線程,執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)。
/**
* 同步執(zhí)行 + 并發(fā)隊(duì)列
* 特點(diǎn):在當(dāng)前線程中執(zhí)行任務(wù),不會開啟新線程,執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)。
*/
- (void)syncConcurrent {
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當(dāng)前線程
NSLog(@"syncConcurrent---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
// 追加任務(wù)1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_sync(queue, ^{
// 追加任務(wù)2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_sync(queue, ^{
// 追加任務(wù)3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
NSLog(@"syncConcurrent---end");
}
輸出結(jié)果:
2018-02-23 20:34:55.095932+0800 YSC-GCD-demo[19892:4996930] currentThread---<NSThread: 0x60400006bbc0>{number = 1, name = main}
2018-02-23 20:34:55.096086+0800 YSC-GCD-demo[19892:4996930] syncConcurrent---begin
2018-02-23 20:34:57.097589+0800 YSC-GCD-demo[19892:4996930] 1---<NSThread: 0x60400006bbc0>{number = 1, name = main}
2018-02-23 20:34:59.099100+0800 YSC-GCD-demo[19892:4996930] 1---<NSThread: 0x60400006bbc0>{number = 1, name = main}
2018-02-23 20:35:01.099843+0800 YSC-GCD-demo[19892:4996930] 2---<NSThread: 0x60400006bbc0>{number = 1, name = main}
2018-02-23 20:35:03.101171+0800 YSC-GCD-demo[19892:4996930] 2---<NSThread: 0x60400006bbc0>{number = 1, name = main}
2018-02-23 20:35:05.101750+0800 YSC-GCD-demo[19892:4996930] 3---<NSThread: 0x60400006bbc0>{number = 1, name = main}
2018-02-23 20:35:07.102414+0800 YSC-GCD-demo[19892:4996930] 3---<NSThread: 0x60400006bbc0>{number = 1, name = main}
2018-02-23 20:35:07.102575+0800 YSC-GCD-demo[19892:4996930] syncConcurrent---end
從同步執(zhí)行 + 并發(fā)隊(duì)列中可看到:
1.所有任務(wù)都是在當(dāng)前線程(主線程)中執(zhí)行的,沒有開啟新的線程(同步執(zhí)行不具備開啟新線程的能力)。
2.所有任務(wù)都在打印的syncConcurrent---begin和syncConcurrent---end之間執(zhí)行的(同步任務(wù)需要等待隊(duì)列的任務(wù)執(zhí)行結(jié)束)。
3.任務(wù)按順序執(zhí)行的。按順序執(zhí)行的原因:雖然并發(fā)隊(duì)列可以開啟多個線程,并且同時執(zhí)行多個任務(wù)。但是因?yàn)楸旧聿荒軇?chuàng)建新線程,只有當(dāng)前線程這一個線程(同步任務(wù)不具備開啟新線程的能力),所以也就不存在并發(fā)。而且當(dāng)前線程只有等待當(dāng)前隊(duì)列中正在執(zhí)行的任務(wù)執(zhí)行完畢之后,才能繼續(xù)接著執(zhí)行下面的操作(同步任務(wù)需要等待隊(duì)列的任務(wù)執(zhí)行結(jié)束)。所以任務(wù)只能一個接一個按順序執(zhí)行,不能同時被執(zhí)行。
2.異步執(zhí)行 + 并發(fā)隊(duì)列
可以開啟多個線程,任務(wù)交替(同時)執(zhí)行。
/**
* 異步執(zhí)行 + 并發(fā)隊(duì)列
* 特點(diǎn):可以開啟多個線程,任務(wù)交替(同時)執(zhí)行。
*/
- (void)asyncConcurrent {
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當(dāng)前線程
NSLog(@"asyncConcurrent---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 追加任務(wù)1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_async(queue, ^{
// 追加任務(wù)2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_async(queue, ^{
// 追加任務(wù)3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
NSLog(@"asyncConcurrent---end");
}
輸出結(jié)果:
2018-02-23 20:36:41.769269+0800 YSC-GCD-demo[19929:5005237] currentThread---<NSThread: 0x604000062d80>{number = 1, name = main}
2018-02-23 20:36:41.769496+0800 YSC-GCD-demo[19929:5005237] asyncConcurrent---begin
2018-02-23 20:36:41.769725+0800 YSC-GCD-demo[19929:5005237] asyncConcurrent---end
2018-02-23 20:36:43.774442+0800 YSC-GCD-demo[19929:5005566] 2---<NSThread: 0x604000266f00>{number = 5, name = (null)}
2018-02-23 20:36:43.774440+0800 YSC-GCD-demo[19929:5005567] 3---<NSThread: 0x60000026f200>{number = 4, name = (null)}
2018-02-23 20:36:43.774440+0800 YSC-GCD-demo[19929:5005565] 1---<NSThread: 0x600000264800>{number = 3, name = (null)}
2018-02-23 20:36:45.779286+0800 YSC-GCD-demo[19929:5005567] 3---<NSThread: 0x60000026f200>{number = 4, name = (null)}
2018-02-23 20:36:45.779302+0800 YSC-GCD-demo[19929:5005565] 1---<NSThread: 0x600000264800>{number = 3, name = (null)}
2018-02-23 20:36:45.779286+0800 YSC-GCD-demo[19929:5005566] 2---<NSThread: 0x604000266f00>{number = 5, name = (null)}
在異步執(zhí)行 + 并發(fā)隊(duì)列中可以看出:
1.除了當(dāng)前線程(主線程),系統(tǒng)又開啟了3個線程,并且任務(wù)是交替/同時執(zhí)行的。(異步執(zhí)行具備開啟新線程的能力。且并發(fā)隊(duì)列可開啟多個線程,同時執(zhí)行多個任務(wù))。
2.所有任務(wù)是在打印的syncConcurrent---begin和syncConcurrent---end之后才執(zhí)行的。說明當(dāng)前線程沒有等待,而是直接開啟了新線程,在新線程中執(zhí)行任務(wù)(異步執(zhí)行不做等待,可以繼續(xù)執(zhí)行任務(wù))。
3.同步執(zhí)行 + 串行隊(duì)列
不會開啟新線程,在當(dāng)前線程執(zhí)行任務(wù)。任務(wù)是串行的,執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)。
/**
* 同步執(zhí)行 + 串行隊(duì)列
* 特點(diǎn):不會開啟新線程,在當(dāng)前線程執(zhí)行任務(wù)。任務(wù)是串行的,執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)。
*/
- (void)syncSerial {
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當(dāng)前線程
NSLog(@"syncSerial---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
// 追加任務(wù)1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_sync(queue, ^{
// 追加任務(wù)2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_sync(queue, ^{
// 追加任務(wù)3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
NSLog(@"syncSerial---end");
}
輸出結(jié)果:
2018-02-23 20:39:37.876811+0800 YSC-GCD-demo[19975:5017162] currentThread---<NSThread: 0x604000079400>{number = 1, name = main}
2018-02-23 20:39:37.876998+0800 YSC-GCD-demo[19975:5017162] syncSerial---begin
2018-02-23 20:39:39.878316+0800 YSC-GCD-demo[19975:5017162] 1---<NSThread: 0x604000079400>{number = 1, name = main}
2018-02-23 20:39:41.879829+0800 YSC-GCD-demo[19975:5017162] 1---<NSThread: 0x604000079400>{number = 1, name = main}
2018-02-23 20:39:43.880660+0800 YSC-GCD-demo[19975:5017162] 2---<NSThread: 0x604000079400>{number = 1, name = main}
2018-02-23 20:39:45.881265+0800 YSC-GCD-demo[19975:5017162] 2---<NSThread: 0x604000079400>{number = 1, name = main}
2018-02-23 20:39:47.882257+0800 YSC-GCD-demo[19975:5017162] 3---<NSThread: 0x604000079400>{number = 1, name = main}
2018-02-23 20:39:49.883008+0800 YSC-GCD-demo[19975:5017162] 3---<NSThread: 0x604000079400>{number = 1, name = main}
2018-02-23 20:39:49.883253+0800 YSC-GCD-demo[19975:5017162] syncSerial---end
在同步執(zhí)行 + 串行隊(duì)列可以看到:
1.所有任務(wù)都是在當(dāng)前線程(主線程)中執(zhí)行的,并沒有開啟新的線程(同步執(zhí)行不具備開啟新線程的能力)。
2.所有任務(wù)都在打印的syncConcurrent---begin和syncConcurrent---end之間執(zhí)行(同步任務(wù)需要等待隊(duì)列的任務(wù)執(zhí)行結(jié)束)。
任務(wù)是按順序執(zhí)行的(串行隊(duì)列每次只有一個任務(wù)被執(zhí)行,任務(wù)一個接一個按順序執(zhí)行)。
4.異步執(zhí)行 + 串行隊(duì)列
會開啟新線程,但是因?yàn)槿蝿?wù)是串行的,執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)
/**
* 異步執(zhí)行 + 串行隊(duì)列
* 特點(diǎn):會開啟新線程,但是因?yàn)槿蝿?wù)是串行的,執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)。
*/
- (void)asyncSerial {
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當(dāng)前線程
NSLog(@"asyncSerial---begin");
dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
// 追加任務(wù)1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_async(queue, ^{
// 追加任務(wù)2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_async(queue, ^{
// 追加任務(wù)3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
NSLog(@"asyncSerial---end");
}
輸出結(jié)果:
2018-02-23 20:41:17.029999+0800 YSC-GCD-demo[20008:5024757] currentThread---<NSThread: 0x604000070440>{number = 1, name = main}
2018-02-23 20:41:17.030212+0800 YSC-GCD-demo[20008:5024757] asyncSerial---begin
2018-02-23 20:41:17.030364+0800 YSC-GCD-demo[20008:5024757] asyncSerial---end
2018-02-23 20:41:19.035379+0800 YSC-GCD-demo[20008:5024950] 1---<NSThread: 0x60000026e100>{number = 3, name = (null)}
2018-02-23 20:41:21.037140+0800 YSC-GCD-demo[20008:5024950] 1---<NSThread: 0x60000026e100>{number = 3, name = (null)}
2018-02-23 20:41:23.042220+0800 YSC-GCD-demo[20008:5024950] 2---<NSThread: 0x60000026e100>{number = 3, name = (null)}
2018-02-23 20:41:25.042971+0800 YSC-GCD-demo[20008:5024950] 2---<NSThread: 0x60000026e100>{number = 3, name = (null)}
2018-02-23 20:41:27.047690+0800 YSC-GCD-demo[20008:5024950] 3---<NSThread: 0x60000026e100>{number = 3, name = (null)}
2018-02-23 20:41:29.052327+0800 YSC-GCD-demo[20008:5024950] 3---<NSThread: 0x60000026e100>{number = 3, name = (null)}
在異步執(zhí)行 + 串行隊(duì)列可以看到:
1.開啟了一條新線程(異步執(zhí)行具備開啟新線程的能力,串行隊(duì)列只開啟一個線程)。
2.所有任務(wù)是在打印的syncConcurrent---begin和syncConcurrent---end之后才開始執(zhí)行的(異步執(zhí)行不會做任何等待,可以繼續(xù)執(zhí)行任務(wù))。
任務(wù)是按順序執(zhí)行的(串行隊(duì)列每次只有一個任務(wù)被執(zhí)行,任務(wù)一個接一個按順序執(zhí)行)。
5.同步執(zhí)行 + 主隊(duì)列
互相等待卡住不可行
死鎖 我在死鎖章節(jié)有詳細(xì)說明 http://m.itdecent.cn/p/d35dae9a3156
/**
* 同步執(zhí)行 + 主隊(duì)列
* 特點(diǎn)(主線程調(diào)用):互等卡主不執(zhí)行。
* 特點(diǎn)(其他線程調(diào)用):不會開啟新線程,執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)。
*/
- (void)syncMain {
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當(dāng)前線程
NSLog(@"syncMain---begin");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
// 追加任務(wù)1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_sync(queue, ^{
// 追加任務(wù)2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_sync(queue, ^{
// 追加任務(wù)3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
NSLog(@"syncMain---end");
}
輸出結(jié)果:
2018-02-23 20:42:36.842892+0800 YSC-GCD-demo[20041:5030982] currentThread---<NSThread: 0x600000078a00>{number = 1, name = main}
2018-02-23 20:42:36.843050+0800 YSC-GCD-demo[20041:5030982] syncMain---begin
(lldb)
在同步執(zhí)行 + 主隊(duì)列可以驚奇的發(fā)現(xiàn):
1.在主線程中使用同步執(zhí)行 + 主隊(duì)列,追加到主線程的任務(wù)1、任務(wù)2、任務(wù)3都不再執(zhí)行了,而且syncMain---end也沒有打印,在XCode 9上還會報(bào)崩潰。這是為什么呢?
2.這是因?yàn)槲覀冊谥骶€程中執(zhí)行syncMain方法,相當(dāng)于把syncMain任務(wù)放到了主線程的隊(duì)列中。而同步執(zhí)行會等待當(dāng)前隊(duì)列中的任務(wù)執(zhí)行完畢,才會接著執(zhí)行。那么當(dāng)我們把任務(wù)1追加到主隊(duì)列中,任務(wù)1就在等待主線程處理完syncMain任務(wù)。而syncMain任務(wù)需要等待任務(wù)1執(zhí)行完畢,才能接著執(zhí)行。
那么,現(xiàn)在的情況就是syncMain任務(wù)和任務(wù)1都在等對方執(zhí)行完畢。這樣大家互相等待,所以就卡住了,所以我們的任務(wù)執(zhí)行不了,而且syncMain---end也沒有打印。
要是如果不在主線程中調(diào)用,而在其他線程中調(diào)用會如何呢?
// 使用 NSThread 的 detachNewThreadSelector 方法會創(chuàng)建線程,并自動啟動線程執(zhí)行
selector 任務(wù)
[NSThread detachNewThreadSelector:@selector(syncMain) toTarget:self withObject:nil];
輸出結(jié)果:
2018-02-23 20:44:19.377321+0800 YSC-GCD-demo[20083:5040347] currentThread---<NSThread: 0x600000272fc0>{number = 3, name = (null)}
2018-02-23 20:44:19.377494+0800 YSC-GCD-demo[20083:5040347] syncMain---begin
2018-02-23 20:44:21.384716+0800 YSC-GCD-demo[20083:5040132] 1---<NSThread: 0x60000006c900>{number = 1, name = main}
2018-02-23 20:44:23.386091+0800 YSC-GCD-demo[20083:5040132] 1---<NSThread: 0x60000006c900>{number = 1, name = main}
2018-02-23 20:44:25.387687+0800 YSC-GCD-demo[20083:5040132] 2---<NSThread: 0x60000006c900>{number = 1, name = main}
2018-02-23 20:44:27.388648+0800 YSC-GCD-demo[20083:5040132] 2---<NSThread: 0x60000006c900>{number = 1, name = main}
2018-02-23 20:44:29.390459+0800 YSC-GCD-demo[20083:5040132] 3---<NSThread: 0x60000006c900>{number = 1, name = main}
2018-02-23 20:44:31.391965+0800 YSC-GCD-demo[20083:5040132] 3---<NSThread: 0x60000006c900>{number = 1, name = main}
2018-02-23 20:44:31.392513+0800 YSC-GCD-demo[20083:5040347] syncMain---end
在其他線程中使用同步執(zhí)行 + 主隊(duì)列可看到:
所有任務(wù)都是在主線程(非當(dāng)前線程)中執(zhí)行的,沒有開啟新的線程(所有放在主隊(duì)列中的任務(wù),都會放到主線程中執(zhí)行)。
所有任務(wù)都在打印的syncConcurrent---begin和syncConcurrent---end之間執(zhí)行(同步任務(wù)需要等待隊(duì)列的任務(wù)執(zhí)行結(jié)束)。
任務(wù)是按順序執(zhí)行的(主隊(duì)列是串行隊(duì)列,每次只有一個任務(wù)被執(zhí)行,任務(wù)一個接一個按順序執(zhí)行)。
為什么現(xiàn)在就不會卡住了呢?
因?yàn)閟yncMain 任務(wù)放到了其他線程里,而任務(wù)1、任務(wù)2、任務(wù)3都在追加到主隊(duì)列中,這三個任務(wù)都會在主線程中執(zhí)行。syncMain 任務(wù)在其他線程中執(zhí)行到追加任務(wù)1到主隊(duì)列中,因?yàn)橹麝?duì)列現(xiàn)在沒有正在執(zhí)行的任務(wù),所以,會直接執(zhí)行主隊(duì)列的任務(wù)1,等任務(wù)1執(zhí)行完畢,再接著執(zhí)行任務(wù)2、任務(wù)3。所以這里不會卡住線程。
6 異步執(zhí)行 + 主隊(duì)列
只在主線程中執(zhí)行任務(wù),執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)
/**
* 異步執(zhí)行 + 主隊(duì)列
* 特點(diǎn):只在主線程中執(zhí)行任務(wù),執(zhí)行完一個任務(wù),再執(zhí)行下一個任務(wù)
*/
- (void)asyncMain {
NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印當(dāng)前線程
NSLog(@"asyncMain---begin");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
// 追加任務(wù)1
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"1---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_async(queue, ^{
// 追加任務(wù)2
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"2---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
dispatch_async(queue, ^{
// 追加任務(wù)3
for (int i = 0; i < 2; ++i) {
[NSThread sleepForTimeInterval:2]; // 模擬耗時操作
NSLog(@"3---%@",[NSThread currentThread]); // 打印當(dāng)前線程
}
});
NSLog(@"asyncMain---end");
}
輸出結(jié)果:
2018-02-23 20:45:49.981505+0800 YSC-GCD-demo[20111:5046708] currentThread---<NSThread: 0x60000006d440>{number = 1, name = main}
2018-02-23 20:45:49.981935+0800 YSC-GCD-demo[20111:5046708] asyncMain---begin
2018-02-23 20:45:49.982352+0800 YSC-GCD-demo[20111:5046708] asyncMain---end
2018-02-23 20:45:51.991096+0800 YSC-GCD-demo[20111:5046708] 1---<NSThread: 0x60000006d440>{number = 1, name = main}
2018-02-23 20:45:53.991959+0800 YSC-GCD-demo[20111:5046708] 1---<NSThread: 0x60000006d440>{number = 1, name = main}
2018-02-23 20:45:55.992937+0800 YSC-GCD-demo[20111:5046708] 2---<NSThread: 0x60000006d440>{number = 1, name = main}
2018-02-23 20:45:57.993649+0800 YSC-GCD-demo[20111:5046708] 2---<NSThread: 0x60000006d440>{number = 1, name = main}
2018-02-23 20:45:59.994928+0800 YSC-GCD-demo[20111:5046708] 3---<NSThread: 0x60000006d440>{number = 1, name = main}
2018-02-23 20:46:01.995589+0800 YSC-GCD-demo[20111:5046708] 3---<NSThread: 0x60000006d440>{number = 1, name = main}
在異步執(zhí)行 + 主隊(duì)列可以看到:
所有任務(wù)都是在當(dāng)前線程(主線程)中執(zhí)行的,并沒有開啟新的線程(雖然異步執(zhí)行具備開啟線程的能力,但因?yàn)槭侵麝?duì)列,所以所有任務(wù)都在主線程中)。
所有任務(wù)是在打印的syncConcurrent---begin和syncConcurrent---end之后才開始執(zhí)行的(異步執(zhí)行不會做任何等待,可以繼續(xù)執(zhí)行任務(wù))。
任務(wù)是按順序執(zhí)行的(因?yàn)橹麝?duì)列是串行隊(duì)列,每次只有一個任務(wù)被執(zhí)行,任務(wù)一個接一個按順序執(zhí)行)。
總結(jié)
1.串行隊(duì)列的特點(diǎn) 任務(wù)按順序執(zhí)行,一個執(zhí)行完畢執(zhí)行下一個任務(wù),無論同步任務(wù)或是異步任務(wù),因?yàn)榇嘘?duì)列 執(zhí)行同步任務(wù)不開辟線程,執(zhí)行異步任務(wù)開辟最多開辟一條線程,所以必須順序執(zhí)行。
2.并行隊(duì)列的特點(diǎn),執(zhí)行異步任務(wù)具備開辟多條線程的能力,執(zhí)行同步任務(wù),順序執(zhí)行。因?yàn)闆]有開辟線程。
3.開不開線程,取決的任務(wù),同步不開新線程,異步開新線程。
4.開幾天線程取決于隊(duì)列,串行隊(duì)列開一條線程,并行隊(duì)列在執(zhí)行多個異步任務(wù)時會開辟多條線程。