之前去面试时被考官给的一道多线程任务执行顺序问题给问到了,之前对这块一直学得不清不楚,现在刚好有空测试一下。下面先上代码与执行结果:
dispatch_queue_t serialQueue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
dispatch_queue_tconcurrentQueue =dispatch_queue_create("并行队列",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//1
for (inti =0; i <10; i++) {
dispatch_sync(serialQueue, ^{
NSLog(@"任务执行中。。。-%d, mainThread:%@",i,[NSThread currentThread]);
});
}
/*
2018-08-22 16:45:56.881958+0800 ttttt[11609:14893507] 任务执行中。。。-0, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882092+0800 ttttt[11609:14893507] 任务执行中。。。-1, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882174+0800 ttttt[11609:14893507] 任务执行中。。。-2, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882236+0800 ttttt[11609:14893507] 任务执行中。。。-3, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882293+0800 ttttt[11609:14893507] 任务执行中。。。-4, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882348+0800 ttttt[11609:14893507] 任务执行中。。。-5, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882469+0800 ttttt[11609:14893507] 任务执行中。。。-6, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882551+0800 ttttt[11609:14893507] 任务执行中。。。-7, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882617+0800 ttttt[11609:14893507] 任务执行中。。。-8, mainThread:{number = 1, name = main}
2018-08-22 16:45:56.882677+0800 ttttt[11609:14893507] 任务执行中。。。-9, mainThread:{number = 1, name = main}
*/
//运行结果是,同步任务在串行队列中,在主线程下串行执行
//2
for (inti=0; i<5; i++) {
dispatch_sync(concurrentQueue, ^{
NSLog(@"同步任务在并行队列执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
/*
同步任务在并行队列执行中....-0
mainThread:{number = 1, name = main}
2018-08-22 16:50:37.411207+0800 ttttt[11688:14904522] 同步任务在并行队列执行中....-1
mainThread:{number = 1, name = main}
2018-08-22 16:50:37.411339+0800 ttttt[11688:14904522] 同步任务在并行队列执行中....-2
mainThread:{number = 1, name = main}
2018-08-22 16:50:37.411417+0800 ttttt[11688:14904522] 同步任务在并行队列执行中....-3
mainThread:{number = 1, name = main}
2018-08-22 16:50:37.411527+0800 ttttt[11688:14904522] 同步任务在并行队列执行中....-4
mainThread:{number = 1, name = main}
*/
//结果,同步任务在并行队列中,在主线程下串行执行
//3
// for(int i=0;i<10;i++){
// dispatch_sync(mainQueue, ^{
// NSLog(@"任务执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
// });
// }
//结果,同步任务在主队列中,锁死
//4
for (inti=0; i<5; i++) {
dispatch_sync(globalQueue, ^{
NSLog(@"同步任务在全局队列执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
/*
2018-08-22 17:03:36.779303+0800 ttttt[11929:14946556] 同步任务在全局队列执行中....-0
mainThread:{number = 1, name = main}
2018-08-22 17:03:36.779507+0800 ttttt[11929:14946556] 同步任务在全局队列执行中....-1
mainThread:{number = 1, name = main}
2018-08-22 17:03:36.779630+0800 ttttt[11929:14946556] 同步任务在全局队列执行中....-2
mainThread:{number = 1, name = main}
2018-08-22 17:03:36.779729+0800 ttttt[11929:14946556] 同步任务在全局队列执行中....-3
mainThread:{number = 1, name = main}
2018-08-22 17:03:36.779884+0800 ttttt[11929:14946556] 同步任务在全局队列执行中....-4
mainThread:{number = 1, name = main}
*/
//结果,同步任务在全局队列中,在主线程下串行执行
//5
for (inti=0; i<10; i++) {
dispatch_async(serialQueue, ^{
NSLog(@"异步任务在串行队列执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
/*
2018-08-22 17:06:58.915475+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-0
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.915556+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-1
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.915690+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-2
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.916051+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-3
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.916435+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-4
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.916613+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-5
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.917091+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-6
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.917218+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-7
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.917451+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-8
mainThread:{number = 3, name = (null)}
2018-08-22 17:06:58.917571+0800 ttttt[11993:14954479] 异步任务在串行队列执行中....-9
mainThread:{number = 3, name = (null)}
*/
//结果,异步任务在串行队列中,是在一个子线程中串行执行
//6
for (inti=0; i<5; i++) {
dispatch_async(concurrentQueue, ^{
NSLog(@"异步任务在并行队列执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
/*
2018-08-22 17:11:37.539218+0800 ttttt[12080:14967734] 异步任务在并行队列执行中....-1
mainThread:{number = 5, name = (null)}
2018-08-22 17:11:37.539219+0800 ttttt[12080:14967733] 异步任务在并行队列执行中....-0
mainThread:{number = 4, name = (null)}
2018-08-22 17:11:37.539249+0800 ttttt[12080:14967736] 异步任务在并行队列执行中....-2
mainThread:{number = 6, name = (null)}
2018-08-22 17:11:37.539522+0800 ttttt[12080:14967744] 异步任务在并行队列执行中....-3
mainThread:{number = 7, name = (null)}
2018-08-22 17:11:37.539566+0800 ttttt[12080:14967745] 异步任务在并行队列执行中....-4
mainThread:{number = 8, name = (null)}
*/
//结果,异步任务在并行队列中,是在多个子线程中并行执行,顺序不确定
//7
for (inti=0; i<7; i++) {
dispatch_async(mainQueue, ^{
NSLog(@"异步任务在主队列执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
/*
2018-08-22 17:18:08.413412+0800 ttttt[12189:14986737] 异步任务在主队列执行中....-1
mainThread:{number = 1, name = main}
2018-08-22 17:18:08.413520+0800 ttttt[12189:14986737] 异步任务在主队列执行中....-2
mainThread:{number = 1, name = main}
2018-08-22 17:18:08.413746+0800 ttttt[12189:14986737] 异步任务在主队列执行中....-3
mainThread:{number = 1, name = main}
2018-08-22 17:18:08.413923+0800 ttttt[12189:14986737] 异步任务在主队列执行中....-4
mainThread:{number = 1, name = main}
2018-08-22 17:18:08.414136+0800 ttttt[12189:14986737] 异步任务在主队列执行中....-5
mainThread:{number = 1, name = main}
2018-08-22 17:18:08.414205+0800 ttttt[12189:14986737] 异步任务在主队列执行中....-6
mainThread:{number = 1, name = main}
*/
//结果,异步任务在主队列中执行,是在主线程中串行执行
//8
for (inti=0; i<6; i++) {
dispatch_async(globalQueue, ^{
NSLog(@"异步任务在全局队列执行中....-%d\n mainThread:%@",i,[NSThread currentThread]);
});
}
/*
2018-08-22 17:22:04.895288+0800 ttttt[12266:14996623] 异步任务在全局队列执行中....-0
mainThread:{number = 9, name = (null)}
2018-08-22 17:22:04.895322+0800 ttttt[12266:14996624] 异步任务在全局队列执行中....-1
mainThread:{number = 10, name = (null)}
2018-08-22 17:22:04.895344+0800 ttttt[12266:14996625] 异步任务在全局队列执行中....-2
mainThread:{number = 11, name = (null)}
2018-08-22 17:22:04.895397+0800 ttttt[12266:14996626] 异步任务在全局队列执行中....-3
mainThread:{number = 12, name = (null)}
2018-08-22 17:22:04.895470+0800 ttttt[12266:14996629] 异步任务在全局队列执行中....-5
mainThread:{number = 14, name = (null)}
2018-08-22 17:22:04.895475+0800 ttttt[12266:14996628] 异步任务在全局队列执行中....-4
mainThread:{number = 13, name = (null)}
*/
//结果,异步任务在全局队列中执行,是在多个子线程中并行执行
总结:
1、同步任务在自定义串行队列、自定义并行队列以及全局队列中执行时,都是在当前线程中串行执行(我的测试代码中是在主线程中提交任务,所以结果显示是在主线程中串行执行);但是同步任务在主队列中执行会造成死锁,死锁具体原因随后在开篇记录。
2、异步任务在自定义串行队列、自定义并行队列以及全局队列中执行时,都是会开辟子线程执行,串行队列会开辟一条子线程串行执行,并行队列和全局队列中会开辟多条子线程并行执行;但是异步任务在主队列中执行时,不会开辟子线程,而是会在主队列所属的主线程中串行执行。