1. 程式人生 > >筆記:對多執行緒技術GCD的簡單總結

筆記:對多執行緒技術GCD的簡單總結

提到 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)}