ios菜鸟关于同步、异步 并发和串行的理解

来源:互联网 发布:清华大学软件工程硕士 编辑:程序博客网 时间:2024/05/17 04:05

    

    迄今为止,做IOS开发已经经历了一年有余的时光了,但是博主对同步和异步、并发和串行一直都一知半解,于是就仔细的学习了一下,在网上查了很多资料,但是都不是很详细,于是博主就决定做一下总结,以 下是博主对 同步异步、串行并发的理解,拿出来与大家分享,如果有错误请大家批评指正;


       首先我们要理清一些概念:

       同步(阻塞) 和异步(非阻塞: 同步(阻塞)和异步(非阻塞) 形容的对象是 线程的执行方式,都是相对于主线程而言的。如果同步执行一个线程,那么主线程就会暂停执行(也就是常说的阻塞),直到同步线程的任务执行完毕,主线程才会执行。异步执行一个线程,主线程会继续执行,不管异步线程的任务有没有完成。

            串行合并发:串行和并法 形容的对象是 线程里的任务 的执行方式,大家都知道,我们可以往一个线程里放一个或者多个任务,如果往一个串行线程中放多个任务,那么里面的任务会一个一个排着队执行,必须上一个执行完,下一个才能执行,先分配的任务先执行。如果往一个并发队列中分配多个任务,所有的任务不必排队,可以同时执行,并且执行的顺序不确定。

         注意 :同步和异步,形容的是线程 执行方式,并发和串行形容的是 线程里的任务的执行方式,博主发现很多人都混淆不清,所以特别声明。希望大家不要再混淆了。          


      只是说概念大家也许觉得枯燥,那我就用GCD来为大家举几个列子吧;


);

dispatch_queue_t gcdQue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);


dispatch_queue_t mainGcd =dispatch_get_main_queue();



在这里 我们获取了程序的 一个全局队列(并发),和主队列,


dispatch_async(gcdQue, ^{

        

        for (int i =0; i <100;i++) {

            

            NSLog(@"E");

        }

        

    });

    



    

    dispatch_async(gcdQue, ^{

        

        for (int i =0; i <100;i++) {

            

            NSLog(@"B");

        }


        

    });

 dispatch_async(mainGcd, ^{

    

        for (int i =0; i <100;i++) {

            

            NSLog(@"F");

        }


    });


我们往并发队列中放了两个任务,一个是打印E,一个是打印B,往主队列中放了一个打印F的任务,如果我们执行之一段代码后会是什么结果呢?

结果是 E B F 可以出现交替出现,我来解释原因:首先我们拿到的是并发队列gcdQue,并且分发了两个任务就是打印E 和打印B,还记得并发的定义么,就是打印E 和打印B可以同时进行,顺序不定,所以会出现E B交替出现的情况,然后我们再来看看 这个并发队列 gcdQue的执行方式:异步,还记得异步的定义么,所以gcdQue线程是不会阻塞主线程的,继续往下执行,主线程的任务是打印F,两个线程同时进行,所以就出现了 E B F,交替出现的情况了。


我们再来看看 把第一个 改成 同步执行



dispatch_sync(gcdQue, ^{

        

        for (int i =0; i < 100;i++) {

            

            NSLog(@"E");

        }

        

    });

    



    

    dispatch_async(gcdQue, ^{

        

        for (int i =0; i < 100;i++) {

            

            NSLog(@"B");

        }


        

    });

 dispatch_async(mainGcd, ^{

    

        for (int i =0; i < 100;i++) {

            

            NSLog(@"F");

        }


    });


运行这段代码,会出现什么情况呢?大家不妨先思考一下,好了,我来公布结果吧


首先打印的是100 个E 然后会出现 B F 交替出现的现象,同样是分配了两个任务,为什么会和上面的结果有出入呢,那我们就要回想一下什么是同步 ,同步是会阻塞主线程的,也就是说 100E 不打印完毕,代码是不会向下执行的,直到打印完毕。也就是说,在打印E期间,gcdQue根本没有接到打印B的任务,而上面那个列子gcdQue都是异步执行,没有阻塞,在打印E期间,又接到打印B的任务,并且可以并发执行,就可以同时打印 E B了。至于为什么B F可以交替,想必大家都知道。



那我们再改一下呢把打印B改成同步执行,结果怎样呢

dispatch_async(gcdQue, ^{

        

        for (int i =0; i < 100;i++) {

            

            NSLog(@"E");

        }

        

    });

    



    

    dispatch_sync(gcdQue, ^{

        

        for (int i =0; i < 100;i++) {

            

            NSLog(@"B");

        }


        

    });

 dispatch_async(mainGcd, ^{

    

        for (int i =0; i < 100;i++) {

            

            NSLog(@"F");

        }


    });



结果如何呢?应该是  E B 交替出现  E F  也可能交替出现 ,但是 必须在  100 次B打印完毕后 才会出现 F,至于为何会EF交替  想必大家会很困惑,我我来说说吧,就是 打印B 和 打印 F 同时进行,至于哪一个先完成,我们不知道,如果在B 打印完成后,打印 E 却还没有完成, 那么接下来就会出现 E F 交替啦。



至于  串行线程,博主就不多做解释了,就是加入的任务会以先进先出的原则执行啦。如果大家还有什么疑问欢迎加博主qq1069875706 讨论。







0 0
原创粉丝点击