一、GCD有三種類型的Queue.
1、main queue:主線程隊列,是一個串行的隊列,一般用來刷新UI。
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新UI
});
2、gloable queue:全局隊列,是一個并行隊列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 網絡請求
});
3、自定義隊列,有兩種:
3.1、serial queue:串行隊列
dispatch_queue_t serial_queue = dispatch_queue_create("com.jueyingxx.serial_queue", DISPATCH_QUEUE_SERIAL);
3.2、concurrent queue:并行隊列
dispatch_queue_t concurrent_queue = dispatch_queue_create("com.jueyingxx.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
二、dispatch_sync和dispatch_async的block中使用串行和并行隊列
1、在dipatch_sync中使用串行隊列
測試代碼
- (void)test_disptch_sync_serial_queue {
dispatch_queue_t serial_queue = dispatch_queue_create("com.jueyingxx.serial_queue", DISPATCH_QUEUE_SERIAL);
for (NSInteger i = 0; i < 10; i++) {
dispatch_sync(serial_queue, ^{
NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
});
}
NSLog(@"running on main thread = %@", [NSThread currentThread]);
}
輸出結果
2016-10-21 10:39:34.649 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==0
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==1
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==2
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==3
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==4
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==5
2016-10-21 10:39:34.650 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==6
2016-10-21 10:39:34.651 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==7
2016-10-21 10:39:34.651 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==8
2016-10-21 10:39:34.651 GCD_Demo[1133:9050010] thread==<NSThread: 0x600000260d40>{number = 1, name = main},
index==9
2016-10-21 10:39:34.677 GCD_Demo[1133:9050010] running on main thread = <NSThread: 0x600000260d40>{number = 1, name = main}
結論:
1、dispatch_sync,并沒有創建新的線程,而是直接在當前的線程(這里是主線程)執行。
2、running on main thread在最后執行的。會阻塞當前線程。
3、符合FIFO的原則。
這就是說,在dispatch_sync中執行使用串行隊列執行任務時,不會創建新的線程,而是直接在當前的線程執行隊列中的任務。
2、在dipatch_sync中使用并行隊列
測試代碼:
- (void)test_disptch_sync_concurrent_queue {
dispatch_queue_t concurrent_queue = dispatch_queue_create("com.jueyingxx.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 10; i++) {
dispatch_sync(concurrent_queue, ^{
NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
});
}
NSLog(@"running on main thread = %@", [NSThread currentThread]);
}
輸出結果:
2016-10-21 10:57:48.055 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==0
2016-10-21 10:57:48.056 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==1
2016-10-21 10:57:48.056 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==2
2016-10-21 10:57:48.056 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==3
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==4
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==5
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==6
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==7
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==8
2016-10-21 10:57:48.057 GCD_Demo[1332:9070229] thread==<NSThread: 0x618000074a00>{number = 1, name = main},
index==9
2016-10-21 10:57:48.081 GCD_Demo[1332:9070229] running on main thread = <NSThread: 0x618000074a00>{number = 1, name = main}
結論:
結果和在dispatch_sync中執行串行隊列的任務結果一模一樣。
為什么?不應該是并行的么,多個線程執行么?
這是因為:dispatch_sync不會創建新的線程的原因。執行并行隊列的任務也在同一個線程。
3、dispatch_async中使用串行隊列
測試代碼:
- (void)test_disptch_async_serial_queue {
dispatch_queue_t serial_queue = dispatch_queue_create("com.jueyingxx.serial_queue", DISPATCH_QUEUE_SERIAL);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(serial_queue, ^{
NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
});
}
NSLog(@"running on main thread = %@", [NSThread currentThread]);
}
輸出結果:
2016-10-21 11:21:17.948 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==0
2016-10-21 11:21:17.948 GCD_Demo[1576:9087107] running on main thread = <NSThread: 0x600000072800>{number = 1, name = main}
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==1
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==2
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==3
2016-10-21 11:21:17.949 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==4
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==5
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==6
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==7
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==8
2016-10-21 11:21:17.950 GCD_Demo[1576:9087144] thread==<NSThread: 0x610000274a00>{number = 4, name = (null)},
index==9
結論:
1、在dispatch_async中使用的線程都為同一個線程,因為他們的地址都是0x610000274a00。
2、輸出結果符合FIFO。
3、running on main thread 的輸出位置是隨機的,說明執行是隨機的。這個符合我們的預期,因為dispatch_async會創建新的線程去執行隊列中的任務,不會阻塞主線程。
4、在dispatch_async中使用并行隊列
測試代碼:
- (void)test_disptch_async_concurrent_queue {
dispatch_queue_t concurrent_queue = dispatch_queue_create("com.jueyingxx.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(concurrent_queue, ^{
NSLog(@"thread==%@, \nindex==%@", [NSThread currentThread], @(i));
});
}
NSLog(@"running on main thread = %@", [NSThread currentThread]);
}
輸出結果:
2016-10-21 11:37:31.875 GCD_Demo[1710:9100006] thread==<NSThread: 0x610000065700>{number = 3, name = (null)},
index==0
2016-10-21 11:37:31.876 GCD_Demo[1710:9100028] thread==<NSThread: 0x618000072480>{number = 11, name = (null)},
index==8
2016-10-21 11:37:31.875 GCD_Demo[1710:9100027] thread==<NSThread: 0x608000073100>{number = 10, name = (null)},
index==7
2016-10-21 11:37:31.875 GCD_Demo[1710:9100004] thread==<NSThread: 0x6180000723c0>{number = 6, name = (null)},
index==3
2016-10-21 11:37:31.875 GCD_Demo[1710:9099961] running on main thread = <NSThread: 0x618000068240>{number = 1, name = main}
2016-10-21 11:37:31.875 GCD_Demo[1710:9100026] thread==<NSThread: 0x608000073080>{number = 8, name = (null)},
index==6
2016-10-21 11:37:31.875 GCD_Demo[1710:9100024] thread==<NSThread: 0x6180000724c0>{number = 7, name = (null)},
index==4
2016-10-21 11:37:31.876 GCD_Demo[1710:9100029] thread==<NSThread: 0x618000072680>{number = 12, name = (null)},
index==9
2016-10-21 11:37:31.875 GCD_Demo[1710:9100003] thread==<NSThread: 0x608000072c40>{number = 5, name = (null)},
index==2
2016-10-21 11:37:31.875 GCD_Demo[1710:9100020] thread==<NSThread: 0x618000072240>{number = 4, name = (null)},
index==1
2016-10-21 11:37:31.875 GCD_Demo[1710:9100025] thread==<NSThread: 0x61000006a980>{number = 9, name = (null)},
index==5
結論:
1、輸出結果每次都不同,說明我們的輸出結果是并發的,并且是由多個線程同時執行的。
2、每次打印的線程地址不同,說明是并發的。
3、running on main thread位置是隨機的,說明不會阻塞主線程。
當然線程的總數量是有限制的,不是會無限制的創建新的線程的。