同步异步执行顺序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/IOSSHAN/article/details/83144318

同步和异步决定了要不要开启新的线程

同步(sync):在当前线程中执行任务,不具备开启新线程的能力
异步(async):在新的线程中执行任务,具备开启新线程的能力

并发和串行决定了任务的执行方式

并发:多个任务并发(同时)执行

串行:一个任务执行完毕后,再执行下一个任务

在这里插入图片描述

关于同步异步串行并行的执行顺序,做如下实验:


1 全局队列异步执行

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
    NSLog(@"2");
});
dispatch_async(queue, ^{
    NSLog(@"3");
});
NSLog(@"4");

执行结果:1 4 2 3

解释:1先打印 23异步执行,在新的线程,不管有没有打印,直接执行4

执行了好几次,一直是这个结果,难道这是必然的吗?

4一定在23前面吗?

对代码做如下处理:对4加上一个300的打印循环

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
    NSLog(@"22");
});
dispatch_async(queue, ^{
    NSLog(@"333");
});

for(int i = 0; i<300; i++)
{
    NSLog(@"4");
}

多次运行出现如下结果:

2018-08-22 18:18:45.808029+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.808226+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.808276+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.774753+0800 Test2018[2149:1050723] 22
2018-08-22 18:18:45.811065+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.774814+0800 Test2018[2149:1050788] 333
2018-08-22 18:18:45.811114+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.811191+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.811245+0800 Test2018[2149:1050563] 4
2018-08-22 18:18:45.811298+0800 Test2018[2149:1050563] 4

说明,23异步执行,不一定非要在最后才执行,不过,异步执行需要时间,因此,一般情况是慢于主线程的打印操作

2一定在3前面吗?

同样,对2做300次的打印循环:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
    for(int i = 0; i<300; i++)
    {
        NSLog(@"22");
    }
});
dispatch_async(queue, ^{
    NSLog(@"333");
});
NSLog(@"4");

出现以下结果:

2018-08-22 18:25:26.215547+0800 Test2018[2154:1051708] 22
2018-08-22 18:25:26.215586+0800 Test2018[2154:1051708] 22
2018-08-22 18:25:26.205837+0800 Test2018[2154:1051712] 333
2018-08-22 18:25:26.218334+0800 Test2018[2154:1051708] 22
2018-08-22 18:25:26.218402+0800 Test2018[2154:1051708] 22

说明,并不是2执行完才执行3

以上说明,只针对题的话,打印是1423。但是,如果抛开题的话,1是先执行,23交替执行,一般是先执行2再执行3,4是在主线程,比子线程打印快,因此,4比23先打印,但是并不是4打印完之后才执行23,是4比较快而已,23子线程比较慢

1打印 4是主线程,23是子线程,因此,4比23先开始。2比3先开始

2 全局队列同步执行

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_sync(queue, ^{
    NSLog(@"2");
});
dispatch_sync(queue, ^{
    NSLog(@"3");
});
NSLog(@"4");

执行结果:1 2 3 4

解释:1先打印 23同步执行,不开启新的线程,所以,只能顺序执行:1234

3 全局队列一同步一异步执行

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_async(queue, ^{
    NSLog(@"2---%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
    NSLog(@"3---%@",[NSThread currentThread]);
});
NSLog(@"4");

执行结果:1 3 4 2

2018-08-22 17:56:27.046521+0800 Test2018[2127:1046667] 1
2018-08-22 17:56:27.047417+0800 Test2018[2127:1046667] 3---<NSThread: 0x17007a5c0>{number = 1, name = main}
2018-08-22 17:56:27.047518+0800 Test2018[2127:1046667] 4
2018-08-22 17:56:27.048704+0800 Test2018[2127:1046686] 2---<NSThread: 0x17426c380>{number = 3, name = (null)}

解释:1先打印 3因为是同步,所以34顺序执行,2是子线程,所以耗时,在最后执行

4 全局队列一异步一同步执行

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"1");
dispatch_sync(queue, ^{
    NSLog(@"2");
});
dispatch_async(queue, ^{
    NSLog(@"3");
});
NSLog(@"4");

执行结果:1 2 4 3

解释:1先打印 2因为是同步,所以顺序执行2,3是异步线程,耗时,因此在最后


5 串行队列异步执行

dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
    NSLog(@"2");
});
dispatch_async(queue, ^{
    NSLog(@"3");
});
NSLog(@"4");

执行结果:1 4 2 3

对于1先打印没有异议,但4一定在2和3的前面吗?一定是4执行完之后,才执行2和3吗?2一定在3的前面吗?

为4增加300个循环

dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
    NSLog(@"1");
    dispatch_async(queue, ^{
        NSLog(@"2-%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3-%@", [NSThread currentThread]);
    });
    for (int i = 0; i<300; i++) {
        NSLog(@"4-%@", [NSThread currentThread]);
    }

结果如下:

2018-10-18 13:41:43.992993+0800 test001[2284:162778] 1
2018-10-18 13:41:43.993228+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}
2018-10-18 13:41:43.993252+0800 test001[2284:162835] 2-<NSThread: 0x60400027a580>{number = 3, name = (null)}
2018-10-18 13:41:43.993364+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}
2018-10-18 13:41:43.993383+0800 test001[2284:162835] 3-<NSThread: 0x60400027a580>{number = 3, name = (null)}
2018-10-18 13:41:43.993497+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}
2018-10-18 13:41:43.993645+0800 test001[2284:162778] 4-<NSThread: 0x600000078540>{number = 1, name = main}

4是同步,比异步2、3快,但并不是4执行完毕后才执行2和3;2和3是异步执行,具有开启新线程的能力,在开启新的线程后,CPU在线程中切换执行,因此会出现1424344这样的结果。

更进一步:
对上述代码添加多行打印:

dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
    NSLog(@"1");
    dispatch_async(queue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"2-%@", [NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i<10; i++) {
            NSLog(@"3-%@", [NSThread currentThread]);
        }
    });
    for (int i = 0; i<30; i++) {
        NSLog(@"4-%@", [NSThread currentThread]);
    }

打印结果如下:

2018-10-18 13:47:42.759085+0800 test001[2363:167342] 1
2018-10-18 13:47:42.759324+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.759352+0800 test001[2363:167390] 2-<NSThread: 0x60400046c880>{number = 3, name = (null)}
2018-10-18 13:47:42.759529+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.759758+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.759763+0800 test001[2363:167390] 2-<NSThread: 0x60400046c880>{number = 3, name = (null)}
2018-10-18 13:47:42.760094+0800 test001[2363:167342] 4-<NSThread: 0x600000263480>{number = 1, name = main}
2018-10-18 13:47:42.760178+0800 test001[2363:167390] 2-<NSThread: 0x60400046c880>{number = 3, name = (null)}

可以看出,CUP是在多个线程(2、4)中切换打印的。

那么,一定在3前面吗?

dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
    NSLog(@"1");
    dispatch_async(queue, ^{
        for (int i = 0; i<50; i++) {
            NSLog(@"2-%@", [NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i = 0; i<50; i++) {
            NSLog(@"3-%@", [NSThread currentThread]);
        }
    });
    
    NSLog(@"4");
    NSLog(@"4-%@", [NSThread currentThread]);

结果如下:

2018-10-18 13:53:08.622294+0800 test001[2445:171837] 1
2018-10-18 13:53:08.622439+0800 test001[2445:171837] 4
2018-10-18 13:53:08.622512+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.622685+0800 test001[2445:171837] 4-<NSThread: 0x604000069600>{number = 1, name = main}
2018-10-18 13:53:08.622699+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.623103+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
...(全是2省略)
2018-10-18 13:53:08.648776+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.648984+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.650128+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652104+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652411+0800 test001[2445:171890] 2-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652596+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652757+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.652907+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.653042+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.653188+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}
2018-10-18 13:53:08.653386+0800 test001[2445:171890] 3-<NSThread: 0x60400027b580>{number = 3, name = (null)}

可以看出,2一定会在3前面,即2执行完毕后,才执行3。
异步串行,会开启新的线程,但是只会开启一条,而且是顺序串行。因此,2执行完毕后才执行3。

总结:异步串行,只会开启一条线程。2、3顺序确定,2一定在3前面。但是2、4以及3、4这种子线程和主线程之间,CPU可以切换执行


6 串行队列同步执行

dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_sync(queue, ^{
    NSLog(@"2");
});
dispatch_sync(queue, ^{
    NSLog(@"3");
});
NSLog(@"4");

执行结果:1 2 3 4
解释:1先打印;因为是串行,一个接一个的执行,因为是同步,所以不具备开启新线程的能力,所以会顺序执行。


7 串行队列一异步一同步执行

dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
    NSLog(@"2");
});
dispatch_sync(queue, ^{
    NSLog(@"3");
});
NSLog(@"4");

执行结果:1 2 3 4
解释:


8 串行队列一同步一异步执行

dispatch_queue_t queue = dispatch_queue_create("shan", NULL);
NSLog(@"1");
dispatch_sync(queue, ^{
    NSLog(@"2");
});
dispatch_async(queue, ^{
    NSLog(@"3");
});
NSLog(@"4");

执行结果:1 2 3 4
解释:

猜你喜欢

转载自blog.csdn.net/IOSSHAN/article/details/83144318