筆記:對多執行緒技術GCD的簡單總結
阿新 • • 發佈:2019-01-04
提到 GCD 首先應該明白六個概念:序列佇列(DISPATCH_QUEUE_SERIAL)、並行佇列(DISPATCH_QUEUE_CONCURRENT)、同步執行(dispatch_sync)、非同步執行(dispatch_async)、
全域性佇列和主佇列,今天主要是先總結一下前四個概念,因為全域性佇列和主佇列比較重要,是最常用到了,放到下一章單獨講。
序列佇列:佇列中的任務是順序地執行,前一個任務執行完之後再執行下一個任務,一個接一個的執行。(中午排隊買飯)
並行佇列:佇列中的任務是同時地執行,齊頭並進。(賽跑)
同步執行:在當前執行緒中執行 + 等待任務執行完畢
非同步執行:在子執行緒中執行 + 不等待任務執行完畢
看程式碼:
一、序列佇列同步執行:(在當前執行緒中順序的執行,等待任務執行結束再執行下面的程式碼)
結果列印:- (void)viewDidLoad { [super viewDidLoad]; [self serialQueueSync]; } // 序列佇列同步執行 -(void)serialQueueSync{ //建立序列佇列 dispatch_queue_t queue = dispatch_queue_create("firstSerialQueue", DISPATCH_QUEUE_SERIAL); NSLog(@"現在開始執行了--%@",[NSThread currentThread]); //新增兩個任務到佇列中 同步執行 dispatch_sync(queue, ^{ for (int i = 0; i < 5; i ++) { [NSThread sleepForTimeInterval:1.0]; NSLog(@"+++++++%@",[NSThread currentThread]); } }); NSLog(@"列印+結束"); dispatch_sync(queue, ^{ for (int i = 0; i < 5; i ++) { [NSThread sleepForTimeInterval:1.0]; NSLog(@"_______%@",[NSThread currentThread]); } }); NSLog(@"列印-結束"); }
2018-03-17 15:48:13.781 3[2075:153871] 現在開始執行了--<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:14.782 3[2075:153871] +++++++<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:15.783 3[2075:153871] +++++++<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:16.785 3[2075:153871] +++++++<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:17.786 3[2075:153871] +++++++<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:18.788 3[2075:153871] +++++++<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:18.788 3[2075:153871] 列印+結束 2018-03-17 15:48:19.790 3[2075:153871] _______<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:20.791 3[2075:153871] _______<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:21.792 3[2075:153871] _______<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:22.793 3[2075:153871] _______<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:23.794 3[2075:153871] _______<NSThread: 0x60000007ea00>{number = 1, name = main} 2018-03-17 15:48:23.795 3[2075:153871] 列印-結束
二、並行佇列同步執行(雖然並行佇列是同時執行,但因為是同步執行,所以是在當前的執行緒順序執行)
// 並行佇列同步執行 -(void)concurrentQueueSync{ // 建立並行對列 dispatch_queue_t queue = dispatch_queue_create("firstConcurrentQueue", DISPATCH_QUEUE_CONCURRENT); NSLog(@"開始執行了--%@",[NSThread currentThread]); // 新增兩個任務到佇列中同步執行 dispatch_sync(queue, ^{ for (int i = 0; i < 5; i ++) { [NSThread sleepForTimeInterval:1.0]; NSLog(@"+++++++%@",[NSThread currentThread]); } }); NSLog(@"列印+結束%@",[NSThread currentThread]); dispatch_sync(queue, ^{ for (int i = 0; i < 5; i ++) { [NSThread sleepForTimeInterval:1.0]; NSLog(@"------%@",[NSThread currentThread]); } }); NSLog(@"列印-結束%@",[NSThread currentThread]); }
列印結果:
2018-03-17 16:02:00.807 3[2302:182308] 開始執行了--<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:01.809 3[2302:182308] +++++++<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:02.810 3[2302:182308] +++++++<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:03.812 3[2302:182308] +++++++<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:04.814 3[2302:182308] +++++++<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:05.815 3[2302:182308] +++++++<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:05.816 3[2302:182308] 列印+結束<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:06.817 3[2302:182308] ------<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:07.819 3[2302:182308] ------<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:08.821 3[2302:182308] ------<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:09.823 3[2302:182308] ------<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:10.824 3[2302:182308] ------<NSThread: 0x600000070500>{number = 1, name = main}
2018-03-17 16:02:10.825 3[2302:182308] 列印-結束<NSThread: 0x600000070500>{number = 1, name = main}
三、序列佇列非同步執行(在子執行緒中一個接一個地執行,不等待任務執行結束)
// 序列佇列非同步執行
-(void)serialQueueAsync{
// 建立序列佇列
dispatch_queue_t queue = dispatch_queue_create("secondSerialQueue", DISPATCH_QUEUE_SERIAL);
// 新增兩個任務到序列佇列中非同步執行
dispatch_async(queue, ^{
for (int i = 0; i < 5; i ++) {
[NSThread sleepForTimeInterval:1.0];
NSLog(@"+++++++%@",[NSThread currentThread]);
}
});
NSLog(@"列印+結束%@",[NSThread currentThread]);
dispatch_async(queue, ^{
for (int i = 0; i < 5; i ++) {
[NSThread sleepForTimeInterval:1.0];
NSLog(@"-------%@",[NSThread currentThread]);
}
});
NSLog(@"列印-結束%@",[NSThread currentThread]);
}
列印結果:
2018-03-17 16:12:31.110 3[2465:203817] 列印+結束<NSThread: 0x60000006bec0>{number = 1, name = main}
2018-03-17 16:12:31.111 3[2465:203817] 列印-結束<NSThread: 0x60000006bec0>{number = 1, name = main}
2018-03-17 16:12:32.113 3[2465:204136] +++++++<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:33.118 3[2465:204136] +++++++<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:34.124 3[2465:204136] +++++++<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:35.129 3[2465:204136] +++++++<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:36.131 3[2465:204136] +++++++<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:37.137 3[2465:204136] -------<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:38.141 3[2465:204136] -------<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:39.142 3[2465:204136] -------<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:40.143 3[2465:204136] -------<NSThread: 0x600000075600>{number = 3, name = (null)}
2018-03-17 16:12:41.145 3[2465:204136] -------<NSThread: 0x600000075600>{number = 3, name = (null)}
四、並行佇列非同步執行(在子執行緒中同時執行,不等待任務執行結束)
// 並行佇列非同步執行
-(void)concurrentQueueAsync{
// 建立並行佇列
dispatch_queue_t queue = dispatch_queue_create("secondConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
// 新增兩個任務到並行佇列中非同步執行
dispatch_async(queue, ^{
for (int i = 0; i < 5; i ++) {
[NSThread sleepForTimeInterval:1.0];
NSLog(@"+++++++%@",[NSThread currentThread]);
}
});
NSLog(@"列印+結束%@",[NSThread currentThread]);
dispatch_async(queue, ^{
for (int i = 0; i < 5; i ++) {
[NSThread sleepForTimeInterval:1.0];
NSLog(@"-------%@",[NSThread currentThread]);
}
});
NSLog(@"列印-結束%@",[NSThread currentThread]);
}
列印結果:
2018-03-17 16:17:21.031 3[2548:213984] 列印+結束<NSThread: 0x6080000678c0>{number = 1, name = main}
2018-03-17 16:17:21.031 3[2548:213984] 列印-結束<NSThread: 0x6080000678c0>{number = 1, name = main}
2018-03-17 16:17:22.036 3[2548:214042] +++++++<NSThread: 0x600000071cc0>{number = 3, name = (null)}
2018-03-17 16:17:22.036 3[2548:214040] -------<NSThread: 0x60800006ab00>{number = 4, name = (null)}
2018-03-17 16:17:23.041 3[2548:214042] +++++++<NSThread: 0x600000071cc0>{number = 3, name = (null)}
2018-03-17 16:17:23.041 3[2548:214040] -------<NSThread: 0x60800006ab00>{number = 4, name = (null)}
2018-03-17 16:17:24.047 3[2548:214040] -------<NSThread: 0x60800006ab00>{number = 4, name = (null)}
2018-03-17 16:17:24.047 3[2548:214042] +++++++<NSThread: 0x600000071cc0>{number = 3, name = (null)}
2018-03-17 16:17:25.053 3[2548:214042] +++++++<NSThread: 0x600000071cc0>{number = 3, name = (null)}
2018-03-17 16:17:25.053 3[2548:214040] -------<NSThread: 0x60800006ab00>{number = 4, name = (null)}
2018-03-17 16:17:26.057 3[2548:214042] +++++++<NSThread: 0x600000071cc0>{number = 3, name = (null)}
2018-03-17 16:17:26.057 3[2548:214040] -------<NSThread: 0x60800006ab00>{number = 4, name = (null)}