一、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位置是随机的,说明不会阻塞主线程。
当然线程的总数量是有限制的,不是会无限制的创建新的线程的。