多线程中队列和同/异步执行问题

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

队列分为并行队列和串行队列,执行方式分为同步执行和异步执行,那么组合一下就有四种方式,下面我会用GCD来验证和总结一下各个组合的特性。

并发队列,同步执行

//并发队列+同步执行
//不会开启新线程,任务顺序执行
-(void)test1{
    NSLog(@"并发队列+同步执行");
    //DISPATCH_QUEUE_CONCURRENT  并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    //dispatch_sync 同步执行
    dispatch_sync(queue, ^{
        for (int i = 0; i < 5; i ++) {
            NSLog(@"1------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 5; i ++) {
            NSLog(@"2------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 5; i ++) {
            NSLog(@"3------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"end");
}

打印结果:

2018-08-30 11:30:39.604191+0800 GCD_demo[1890:93476] 并发队列+同步执行
2018-08-30 11:30:39.604342+0800 GCD_demo[1890:93476] 1------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.604441+0800 GCD_demo[1890:93476] 1------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.604538+0800 GCD_demo[1890:93476] 1------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.604705+0800 GCD_demo[1890:93476] 1------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.604818+0800 GCD_demo[1890:93476] 1------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.604929+0800 GCD_demo[1890:93476] 2------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.604993+0800 GCD_demo[1890:93476] 2------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605059+0800 GCD_demo[1890:93476] 2------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605132+0800 GCD_demo[1890:93476] 2------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605226+0800 GCD_demo[1890:93476] 2------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605344+0800 GCD_demo[1890:93476] 3------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605472+0800 GCD_demo[1890:93476] 3------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605610+0800 GCD_demo[1890:93476] 3------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605752+0800 GCD_demo[1890:93476] 3------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605817+0800 GCD_demo[1890:93476] 3------<NSThread: 0x60c00007e740>{number = 1, name = main}
2018-08-30 11:30:39.605943+0800 GCD_demo[1890:93476] end

并发队列同步执行时,任务都是顺序执行的,且没有开启新的线程。

并发队列,异步执行

//并发队列+异步执行
//会开启新的线程,任务执行无序
-(void)test2{
    NSLog(@"并发队列+异步执行");
    //DISPATCH_QUEUE_CONCURRENT  并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    //dispatch_async 异步执行
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"1------%@",[NSThread currentThread]);
        }
    });
    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]);
        }
    });
    NSLog(@"end");
}

打印结果:

2018-08-30 11:36:05.283473+0800 GCD_demo[1976:100239] 并发队列+异步执行
2018-08-30 11:36:05.283615+0800 GCD_demo[1976:100239] end
2018-08-30 11:36:05.283726+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.283732+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.283751+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.283854+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.283973+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.284024+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.284093+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.284196+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.284838+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.284846+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.284933+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.285001+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.285234+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.285543+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.285707+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.285836+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.286403+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.286535+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.286657+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.287023+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.287205+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.287325+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.287674+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.287775+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.287914+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.288021+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.288105+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}
2018-08-30 11:36:05.288205+0800 GCD_demo[1976:100298] 1------<NSThread: 0x608000265980>{number = 3, name = (null)}
2018-08-30 11:36:05.288296+0800 GCD_demo[1976:100297] 3------<NSThread: 0x60c00027b880>{number = 5, name = (null)}
2018-08-30 11:36:05.288512+0800 GCD_demo[1976:100292] 2------<NSThread: 0x604000262bc0>{number = 4, name = (null)}

并发队列异步执行时,先执行了主线程的代码,然后开启了新的线程执行各自的任务,任务执行无固定顺序,每次运行的打印结果也不一定相同。

串行队列,同步执行

//串行队列+同步执行
//不会开启新线程,任务顺序执行
-(void)test3{
    NSLog(@"串行队列+同步执行");
    //DISPATCH_QUEUE_SERIAL  串行队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    //dispatch_sync 同步执行
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"1------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"2------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"3------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"end");
}

打印结果:

2018-08-30 11:39:52.645772+0800 GCD_demo[2026:103893] 串行队列+同步执行
2018-08-30 11:39:52.645956+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646063+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646147+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646216+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646307+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646403+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646481+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646605+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646681+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646747+0800 GCD_demo[2026:103893] 1------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646820+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646909+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.646972+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647053+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647140+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647294+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647442+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647514+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647629+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647765+0800 GCD_demo[2026:103893] 2------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.647866+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.648214+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.648290+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.648397+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.648477+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.648680+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.648844+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.648980+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.649131+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.649276+0800 GCD_demo[2026:103893] 3------<NSThread: 0x600000076500>{number = 1, name = main}
2018-08-30 11:39:52.649345+0800 GCD_demo[2026:103893] end

串行队列同步执行时,不会开启新线程,任务顺序执行。

串行队列,异步执行

//串行队列+异步执行
//会开启一条新线程,顺序执行任务
-(void)test4{
    NSLog(@"串行队列+异步执行");
    //DISPATCH_QUEUE_SERIAL  串行队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    //dispatch_async 异步执行
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i ++) {
            NSLog(@"1------%@",[NSThread currentThread]);
        }
    });
    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]);
        }
    });
    NSLog(@"end");
}

打印结果:

2018-08-30 11:42:34.493681+0800 GCD_demo[2093:106736] 串行队列+异步执行
2018-08-30 11:42:34.493803+0800 GCD_demo[2093:106736] end
2018-08-30 11:42:34.493861+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.494018+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.494559+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.494908+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.495473+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.495707+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.495842+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.496156+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.496285+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.496489+0800 GCD_demo[2093:106849] 1------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.496680+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.497072+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.497162+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.497303+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.498035+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.498943+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.499458+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.499930+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.500762+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.501457+0800 GCD_demo[2093:106849] 2------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.501728+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.502122+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.502631+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.502946+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.503777+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.503851+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.503980+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.504204+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.504339+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}
2018-08-30 11:42:34.504483+0800 GCD_demo[2093:106849] 3------<NSThread: 0x604000073b00>{number = 3, name = (null)}

串行队列异步执行时,会先执行完主线程中的代码,然后开启一条新的线程来顺序执行任务。

猜你喜欢

转载自blog.csdn.net/aaaaazq/article/details/82219118