直接运行代码
//创建并发队列
dispatch_queue_t queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 10; i++) {
//异步 + 并发队列 --> 系统会分配子线程
dispatch_async(queue, ^{
NSLog(@"+++%@",[NSThread currentThread]);
NSLog(@"&&&%@ \t num:%@",[NSThread currentThread],@(i));
NSLog(@"---%@",[NSThread currentThread]);
});
}
运行结果
2022-07-25 22:14:20.564617+0800 SyncDemo[1050:15060] +++{number = 6, name = (null)}
2022-07-25 22:14:20.564622+0800 SyncDemo[1050:15065] +++{number = 4, name = (null)}
2022-07-25 22:14:20.564632+0800 SyncDemo[1050:15061] +++{number = 5, name = (null)}
2022-07-25 22:14:20.564617+0800 SyncDemo[1050:15062] +++{number = 7, name = (null)}
2022-07-25 22:14:20.564640+0800 SyncDemo[1050:15064] +++{number = 3, name = (null)}
2022-07-25 22:14:20.564671+0800 SyncDemo[1050:15066] +++{number = 8, name = (null)}
2022-07-25 22:14:20.564673+0800 SyncDemo[1050:15065] &&&{number = 4, name = (null)} num:2
2022-07-25 22:14:20.564676+0800 SyncDemo[1050:15060] &&&{number = 6, name = (null)} num:1
2022-07-25 22:14:20.564701+0800 SyncDemo[1050:15064] &&&{number = 3, name = (null)} num:4
2022-07-25 22:14:20.564761+0800 SyncDemo[1050:15065] ---{number = 4, name = (null)}
2022-07-25 22:14:20.564737+0800 SyncDemo[1050:15066] &&&{number = 8, name = (null)} num:5
2022-07-25 22:14:20.564769+0800 SyncDemo[1050:15062] &&&{number = 7, name = (null)} num:0
2022-07-25 22:14:20.564775+0800 SyncDemo[1050:15068] +++{number = 10, name = (null)}
2022-07-25 22:14:20.564778+0800 SyncDemo[1050:15061] &&&{number = 5, name = (null)} num:3
2022-07-25 22:14:20.564777+0800 SyncDemo[1050:15067] +++{number = 9, name = (null)}
2022-07-25 22:14:20.564802+0800 SyncDemo[1050:15069] +++{number = 11, name = (null)}
2022-07-25 22:14:20.564918+0800 SyncDemo[1050:15060] ---{number = 6, name = (null)}
2022-07-25 22:14:20.564957+0800 SyncDemo[1050:15070] +++{number = 12, name = (null)}
2022-07-25 22:14:20.565042+0800 SyncDemo[1050:15064] ---{number = 3, name = (null)}
2022-07-25 22:14:20.565083+0800 SyncDemo[1050:15066] ---{number = 8, name = (null)}
2022-07-25 22:14:20.565246+0800 SyncDemo[1050:15067] &&&{number = 9, name = (null)} num:6
2022-07-25 22:14:20.565283+0800 SyncDemo[1050:15068] &&&{number = 10, name = (null)} num:7
2022-07-25 22:14:20.565350+0800 SyncDemo[1050:15062] ---{number = 7, name = (null)}
2022-07-25 22:14:20.565426+0800 SyncDemo[1050:15070] &&&{number = 12, name = (null)} num:9
2022-07-25 22:14:20.565435+0800 SyncDemo[1050:15068] ---{number = 10, name = (null)}
2022-07-25 22:14:20.565476+0800 SyncDemo[1050:15067] ---{number = 9, name = (null)}
2022-07-25 22:14:20.565549+0800 SyncDemo[1050:15061] ---{number = 5, name = (null)}
2022-07-25 22:14:20.565588+0800 SyncDemo[1050:15069] &&&{number = 11, name = (null)} num:8
2022-07-25 22:14:20.584224+0800 SyncDemo[1050:15070] ---{number = 12, name = (null)}
2022-07-25 22:14:20.584266+0800 SyncDemo[1050:15069] ---{number = 11, name = (null)}
分析:
1.首先要理解gcd造成的多线程,在当前的代码中也就是dispatch_async{里面的三个NSLog在i为同一个值的时候+++&&&---的先后顺序是固定的,但多个thread一起执行,比如i == 1时thread_a+++&&&已经打印完了,可能这时thread_b打印i == 3时的+++}
&&&7后面是&&&5,但是---7后面是---10。
这个时候使用@synchronized再跑一次看看会有什么变化。
dispatch_queue_t queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 10; i++) {
//异步 + 并发队列 --> 系统会分配子线程
dispatch_async(queue, ^{
NSLog(@"+++%@",[NSThread currentThread]);
//add @synchronized
@synchronized (self) {
NSLog(@"&&&%@ \t num:%@",[NSThread currentThread],@(i));
NSLog(@"---%@",[NSThread currentThread]);
}
});
}
打印结果如下
2022-07-25 22:29:25.413162+0800 SyncDemo[1215:25392] +++{number = 6, name = (null)}
2022-07-25 22:29:25.413184+0800 SyncDemo[1215:25390] +++{number = 4, name = (null)}
2022-07-25 22:29:25.413160+0800 SyncDemo[1215:25386] +++{number = 7, name = (null)}
2022-07-25 22:29:25.413193+0800 SyncDemo[1215:25388] +++{number = 8, name = (null)}
2022-07-25 22:29:25.413159+0800 SyncDemo[1215:25389] +++{number = 3, name = (null)}
2022-07-25 22:29:25.413191+0800 SyncDemo[1215:25387] +++{number = 5, name = (null)}
2022-07-25 22:29:25.413230+0800 SyncDemo[1215:25390] &&&{number = 4, name = (null)} num:4
2022-07-25 22:29:25.413245+0800 SyncDemo[1215:25395] +++{number = 9, name = (null)}
2022-07-25 22:29:25.413283+0800 SyncDemo[1215:25398] +++{number = 12, name = (null)}
2022-07-25 22:29:25.413264+0800 SyncDemo[1215:25396] +++{number = 10, name = (null)}
2022-07-25 22:29:25.413278+0800 SyncDemo[1215:25397] +++{number = 11, name = (null)}
2022-07-25 22:29:25.413301+0800 SyncDemo[1215:25390] ---{number = 4, name = (null)}
2022-07-25 22:29:25.413525+0800 SyncDemo[1215:25392] &&&{number = 6, name = (null)} num:1
2022-07-25 22:29:25.413648+0800 SyncDemo[1215:25392] ---{number = 6, name = (null)}
2022-07-25 22:29:25.413687+0800 SyncDemo[1215:25388] &&&{number = 8, name = (null)} num:3
2022-07-25 22:29:25.413719+0800 SyncDemo[1215:25388] ---{number = 8, name = (null)}
2022-07-25 22:29:25.413780+0800 SyncDemo[1215:25395] &&&{number = 9, name = (null)} num:6
2022-07-25 22:29:25.413851+0800 SyncDemo[1215:25395] ---{number = 9, name = (null)}
2022-07-25 22:29:25.413919+0800 SyncDemo[1215:25386] &&&{number = 7, name = (null)} num:0
2022-07-25 22:29:25.413987+0800 SyncDemo[1215:25386] ---{number = 7, name = (null)}
2022-07-25 22:29:25.414039+0800 SyncDemo[1215:25396] &&&{number = 10, name = (null)} num:7
2022-07-25 22:29:25.414087+0800 SyncDemo[1215:25396] ---{number = 10, name = (null)}
2022-07-25 22:29:25.414146+0800 SyncDemo[1215:25389] &&&{number = 3, name = (null)} num:2
2022-07-25 22:29:25.416470+0800 SyncDemo[1215:25389] ---{number = 3, name = (null)}
2022-07-25 22:29:25.416521+0800 SyncDemo[1215:25397] &&&{number = 11, name = (null)} num:8
2022-07-25 22:29:25.416553+0800 SyncDemo[1215:25397] ---{number = 11, name = (null)}
2022-07-25 22:29:25.416598+0800 SyncDemo[1215:25387] &&&{number = 5, name = (null)} num:5
2022-07-25 22:29:25.416632+0800 SyncDemo[1215:25387] ---{number = 5, name = (null)}
2022-07-25 22:29:25.416679+0800 SyncDemo[1215:25398] &&&{number = 12, name = (null)} num:9
2022-07-25 22:29:25.416717+0800 SyncDemo[1215:25398] ---{number = 12, name = (null)}
这次&&&后边出现的第一个---所对应的thread一定能够对应上,结论就是:@synchronized{内部的代码会保证在多线程的环境中thread_a执行完所有逻辑才会thread_b进入执行逻辑}