@synchronized有什么用

2022-07-24  本文已影响0人  Jack小麻雀_

直接运行代码

    //创建并发队列
    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] +++<NSThread: 0x600002589580>{number = 6, name = (null)}
2022-07-25 22:14:20.564622+0800 SyncDemo[1050:15065] +++<NSThread: 0x6000025c15c0>{number = 4, name = (null)}
2022-07-25 22:14:20.564632+0800 SyncDemo[1050:15061] +++<NSThread: 0x600002594100>{number = 5, name = (null)}
2022-07-25 22:14:20.564617+0800 SyncDemo[1050:15062] +++<NSThread: 0x60000258ec80>{number = 7, name = (null)}
2022-07-25 22:14:20.564640+0800 SyncDemo[1050:15064] +++<NSThread: 0x60000258c140>{number = 3, name = (null)}
2022-07-25 22:14:20.564671+0800 SyncDemo[1050:15066] +++<NSThread: 0x60000258ed80>{number = 8, name = (null)}
2022-07-25 22:14:20.564673+0800 SyncDemo[1050:15065] &&&<NSThread: 0x6000025c15c0>{number = 4, name = (null)}    num:2
2022-07-25 22:14:20.564676+0800 SyncDemo[1050:15060] &&&<NSThread: 0x600002589580>{number = 6, name = (null)}    num:1
2022-07-25 22:14:20.564701+0800 SyncDemo[1050:15064] &&&<NSThread: 0x60000258c140>{number = 3, name = (null)}    num:4
2022-07-25 22:14:20.564761+0800 SyncDemo[1050:15065] ---<NSThread: 0x6000025c15c0>{number = 4, name = (null)}
2022-07-25 22:14:20.564737+0800 SyncDemo[1050:15066] &&&<NSThread: 0x60000258ed80>{number = 8, name = (null)}    num:5
2022-07-25 22:14:20.564769+0800 SyncDemo[1050:15062] &&&<NSThread: 0x60000258ec80>{number = 7, name = (null)}    num:0
2022-07-25 22:14:20.564775+0800 SyncDemo[1050:15068] +++<NSThread: 0x6000025c17c0>{number = 10, name = (null)}
2022-07-25 22:14:20.564778+0800 SyncDemo[1050:15061] &&&<NSThread: 0x600002594100>{number = 5, name = (null)}    num:3
2022-07-25 22:14:20.564777+0800 SyncDemo[1050:15067] +++<NSThread: 0x600002598300>{number = 9, name = (null)}
2022-07-25 22:14:20.564802+0800 SyncDemo[1050:15069] +++<NSThread: 0x6000025c5480>{number = 11, name = (null)}
2022-07-25 22:14:20.564918+0800 SyncDemo[1050:15060] ---<NSThread: 0x600002589580>{number = 6, name = (null)}
2022-07-25 22:14:20.564957+0800 SyncDemo[1050:15070] +++<NSThread: 0x600002587f40>{number = 12, name = (null)}
2022-07-25 22:14:20.565042+0800 SyncDemo[1050:15064] ---<NSThread: 0x60000258c140>{number = 3, name = (null)}
2022-07-25 22:14:20.565083+0800 SyncDemo[1050:15066] ---<NSThread: 0x60000258ed80>{number = 8, name = (null)}
2022-07-25 22:14:20.565246+0800 SyncDemo[1050:15067] &&&<NSThread: 0x600002598300>{number = 9, name = (null)}    num:6
2022-07-25 22:14:20.565283+0800 SyncDemo[1050:15068] &&&<NSThread: 0x6000025c17c0>{number = 10, name = (null)}   num:7
2022-07-25 22:14:20.565350+0800 SyncDemo[1050:15062] ---<NSThread: 0x60000258ec80>{number = 7, name = (null)}
2022-07-25 22:14:20.565426+0800 SyncDemo[1050:15070] &&&<NSThread: 0x600002587f40>{number = 12, name = (null)}   num:9
2022-07-25 22:14:20.565435+0800 SyncDemo[1050:15068] ---<NSThread: 0x6000025c17c0>{number = 10, name = (null)}
2022-07-25 22:14:20.565476+0800 SyncDemo[1050:15067] ---<NSThread: 0x600002598300>{number = 9, name = (null)}
2022-07-25 22:14:20.565549+0800 SyncDemo[1050:15061] ---<NSThread: 0x600002594100>{number = 5, name = (null)}
2022-07-25 22:14:20.565588+0800 SyncDemo[1050:15069] &&&<NSThread: 0x6000025c5480>{number = 11, name = (null)}   num:8
2022-07-25 22:14:20.584224+0800 SyncDemo[1050:15070] ---<NSThread: 0x600002587f40>{number = 12, name = (null)}
2022-07-25 22:14:20.584266+0800 SyncDemo[1050:15069] ---<NSThread: 0x6000025c5480>{number = 11, name = (null)}

分析:
1.首先要理解gcd造成的多线程,在当前的代码中也就是dispatch_async{里面的三个NSLog在i为同一个值的时候+++&&&---的先后顺序是固定的,但多个thread一起执行,比如i == 1时thread_a+++&&&已经打印完了,可能这时thread_b打印i == 3时的+++}

2.&&&和---出现的顺序无法对应,可以看截图更明显 image.png

&&&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] +++<NSThread: 0x600000304f00>{number = 6, name = (null)}
2022-07-25 22:29:25.413184+0800 SyncDemo[1215:25390] +++<NSThread: 0x600000300c80>{number = 4, name = (null)}
2022-07-25 22:29:25.413160+0800 SyncDemo[1215:25386] +++<NSThread: 0x600000350640>{number = 7, name = (null)}
2022-07-25 22:29:25.413193+0800 SyncDemo[1215:25388] +++<NSThread: 0x60000030cc80>{number = 8, name = (null)}
2022-07-25 22:29:25.413159+0800 SyncDemo[1215:25389] +++<NSThread: 0x600000350140>{number = 3, name = (null)}
2022-07-25 22:29:25.413191+0800 SyncDemo[1215:25387] +++<NSThread: 0x6000003094c0>{number = 5, name = (null)}
2022-07-25 22:29:25.413230+0800 SyncDemo[1215:25390] &&&<NSThread: 0x600000300c80>{number = 4, name = (null)}    num:4
2022-07-25 22:29:25.413245+0800 SyncDemo[1215:25395] +++<NSThread: 0x600000350800>{number = 9, name = (null)}
2022-07-25 22:29:25.413283+0800 SyncDemo[1215:25398] +++<NSThread: 0x600000307840>{number = 12, name = (null)}
2022-07-25 22:29:25.413264+0800 SyncDemo[1215:25396] +++<NSThread: 0x600000307580>{number = 10, name = (null)}
2022-07-25 22:29:25.413278+0800 SyncDemo[1215:25397] +++<NSThread: 0x600000351380>{number = 11, name = (null)}
2022-07-25 22:29:25.413301+0800 SyncDemo[1215:25390] ---<NSThread: 0x600000300c80>{number = 4, name = (null)}
2022-07-25 22:29:25.413525+0800 SyncDemo[1215:25392] &&&<NSThread: 0x600000304f00>{number = 6, name = (null)}    num:1
2022-07-25 22:29:25.413648+0800 SyncDemo[1215:25392] ---<NSThread: 0x600000304f00>{number = 6, name = (null)}
2022-07-25 22:29:25.413687+0800 SyncDemo[1215:25388] &&&<NSThread: 0x60000030cc80>{number = 8, name = (null)}    num:3
2022-07-25 22:29:25.413719+0800 SyncDemo[1215:25388] ---<NSThread: 0x60000030cc80>{number = 8, name = (null)}
2022-07-25 22:29:25.413780+0800 SyncDemo[1215:25395] &&&<NSThread: 0x600000350800>{number = 9, name = (null)}    num:6
2022-07-25 22:29:25.413851+0800 SyncDemo[1215:25395] ---<NSThread: 0x600000350800>{number = 9, name = (null)}
2022-07-25 22:29:25.413919+0800 SyncDemo[1215:25386] &&&<NSThread: 0x600000350640>{number = 7, name = (null)}    num:0
2022-07-25 22:29:25.413987+0800 SyncDemo[1215:25386] ---<NSThread: 0x600000350640>{number = 7, name = (null)}
2022-07-25 22:29:25.414039+0800 SyncDemo[1215:25396] &&&<NSThread: 0x600000307580>{number = 10, name = (null)}   num:7
2022-07-25 22:29:25.414087+0800 SyncDemo[1215:25396] ---<NSThread: 0x600000307580>{number = 10, name = (null)}
2022-07-25 22:29:25.414146+0800 SyncDemo[1215:25389] &&&<NSThread: 0x600000350140>{number = 3, name = (null)}    num:2
2022-07-25 22:29:25.416470+0800 SyncDemo[1215:25389] ---<NSThread: 0x600000350140>{number = 3, name = (null)}
2022-07-25 22:29:25.416521+0800 SyncDemo[1215:25397] &&&<NSThread: 0x600000351380>{number = 11, name = (null)}   num:8
2022-07-25 22:29:25.416553+0800 SyncDemo[1215:25397] ---<NSThread: 0x600000351380>{number = 11, name = (null)}
2022-07-25 22:29:25.416598+0800 SyncDemo[1215:25387] &&&<NSThread: 0x6000003094c0>{number = 5, name = (null)}    num:5
2022-07-25 22:29:25.416632+0800 SyncDemo[1215:25387] ---<NSThread: 0x6000003094c0>{number = 5, name = (null)}
2022-07-25 22:29:25.416679+0800 SyncDemo[1215:25398] &&&<NSThread: 0x600000307840>{number = 12, name = (null)}   num:9
2022-07-25 22:29:25.416717+0800 SyncDemo[1215:25398] ---<NSThread: 0x600000307840>{number = 12, name = (null)}

这次&&&后边出现的第一个---所对应的thread一定能够对应上,结论就是:@synchronized{内部的代码会保证在多线程的环境中thread_a执行完所有逻辑才会thread_b进入执行逻辑}

上一篇下一篇

猜你喜欢

热点阅读