GCD的8种搭配方式

OC中多线程方案中,一个比较常用的方案就是GCD
在GCD中有两个概念:

队列

任务


队列 :

-1.串行队列 :在一个时刻,只会调度一个任务在线程上执行(在一个时间点上,这个队列中的任务,只有一个会被线程执行)
dispatch_queue_t queue = dispatch_queue_create("xiao", DISPATCH_QUEUE_SERIAL);
-2.并行队列 :在同一时间,会有多个任务被调度,在线程上执行,每个任务被分配到不同的线程(在一个时间点上,这个队列中的任务,可能会有多个,在不同的线程上同时执行)
dispatch_queue_t queue = dispatch_queue_create("xiao", DISPATCH_QUEUE_CONCURRENT);
-3.全局队列 :是一个特殊的并行队列,这个队列右系统创建,拿来直接用就好
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
-4.主队列 :是一种特殊的串行队列,也是由系统创建
dispatch_queue_t queue = dispatch_get_main_queue();
并行队列,串行队列都遵守FIFO原则(先进先出)

任务:

-1.同步任务 :在当前线程中执行,放到这个线程的最后执行(这一时刻),若果后面还有任务,就加到它后面执行
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
//第一个参数是队列模式(传入上面4中模式中的一种)
//第二个参数是要执行的任务
-2.异步任务 :在新的线程中执行,指派一个空闲的线程来执行(这个任务之前没有任务在执行,会被马上执行)
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

在GCD下,将一个任务放到摸一个线程执行,需要为它指派一个队列,任务方式,因此会有8中组合方法.

-1.串行队列 + 同步任务 :拿出一个任务,在当前线程执行,当执行完后,在从队列中取出一个任务,在当前任务中执行;
- (void)gcdDemo2{

    // 创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("xiao", DISPATCH_QUEUE_SERIAL);

    // 把10个同步任务添加到串行队列中
    for (int i = 0; i < 10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"%d-%@",i,[NSThread currentThread]);
        });
    }

}


##运行结果
2017-02-21 21:37:23.147 08-GCD串行队列[5195:632507] 0-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.148 08-GCD串行队列[5195:632507] 1-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.148 08-GCD串行队列[5195:632507] 2-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.148 08-GCD串行队列[5195:632507] 3-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.148 08-GCD串行队列[5195:632507] 4-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.149 08-GCD串行队列[5195:632507] 5-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.149 08-GCD串行队列[5195:632507] 6-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.149 08-GCD串行队列[5195:632507] 7-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.149 08-GCD串行队列[5195:632507] 8-<NSThread: 0x60000007df40>{number = 1, name = main}
2017-02-21 21:37:23.149 08-GCD串行队列[5195:632507] 9-<NSThread: 0x60000007df40>{number = 1, name = main}
-2.串行队列 + 异步任务 :拿出一个任务,在当前线程之外拿出一个线程来执行任务,当任务执行完毕之后,在从队列中拿出一个任务在这个线程上执行
- (void)gcdDemo2{

    // 创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("xiao", DISPATCH_QUEUE_SERIAL);

    // 把10个异步任务添加到串行队列中
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"%d-%@",i,[NSThread currentThread]);
        });
    }

}

##运行结果
2017-02-21 21:35:36.440 08-GCD串行队列[5165:630854] 0-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.440 08-GCD串行队列[5165:630854] 1-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.440 08-GCD串行队列[5165:630854] 2-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.441 08-GCD串行队列[5165:630854] 3-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.441 08-GCD串行队列[5165:630854] 4-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.441 08-GCD串行队列[5165:630854] 5-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.441 08-GCD串行队列[5165:630854] 6-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.441 08-GCD串行队列[5165:630854] 7-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.442 08-GCD串行队列[5165:630854] 8-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
2017-02-21 21:35:36.442 08-GCD串行队列[5165:630854] 9-<NSThread: 0x60800007dc40>{number = 3, name = (null)}
-3.并行队列 + 同步任务 :有序的取出一个任务,放到当前线程执行,执行完毕之后在取出下一个任务执行
- (void)gcdDemo1{
    // 创建一个并行队列
    dispatch_queue_t queue = dispatch_queue_create("xiao", DISPATCH_QUEUE_CONCURRENT);
    // 将10个同步任务添加到并行队列中
    for (int i = 0; i < 10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"%d-%@",i,[NSThread currentThread]);
        });
    }
}

##运行结果
2017-02-21 22:20:19.479 09-GCD并行队列[5297:647011] 0-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.480 09-GCD并行队列[5297:647011] 1-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.482 09-GCD并行队列[5297:647011] 2-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.482 09-GCD并行队列[5297:647011] 3-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.483 09-GCD并行队列[5297:647011] 4-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.483 09-GCD并行队列[5297:647011] 5-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.483 09-GCD并行队列[5297:647011] 6-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.483 09-GCD并行队列[5297:647011] 7-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.483 09-GCD并行队列[5297:647011] 8-<NSThread: 0x608000072200>{number = 1, name = main}
2017-02-21 22:20:19.484 09-GCD并行队列[5297:647011] 9-<NSThread: 0x608000072200>{number = 1, name = main}
-4.并行队列 + 异步任务 :有序的取出多个任务,分配到不同的线程上同时执行,每当有一个线程执行完毕之后,会继续从队列中拿一个出来继续执行,虽然取出的时候是有序的,但是每一个线程执行完毕的时间是不同的,不一定先执行的任务先完成,所以会有下面的结果
- (void)gcdDemo2{
    // 创建一个并行的队列
    dispatch_queue_t queue = dispatch_queue_create("xiao", DISPATCH_QUEUE_CONCURRENT);
    // 将10个异步任务添加到并行队列中
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"%d-%@",i,[NSThread currentThread]);
        });
    }
}

##运行结果
2017-02-21 22:25:12.606 09-GCD并行队列[5321:649930] 1-<NSThread: 0x60800007b3c0>{number = 4, name = (null)}
2017-02-21 22:25:12.606 09-GCD并行队列[5321:649931] 0-<NSThread: 0x60800007b380>{number = 3, name = (null)}
2017-02-21 22:25:12.607 09-GCD并行队列[5321:649933] 3-<NSThread: 0x60800007b500>{number = 6, name = (null)}
2017-02-21 22:25:12.607 09-GCD并行队列[5321:649945] 2-<NSThread: 0x60800007b480>{number = 5, name = (null)}
2017-02-21 22:25:12.607 09-GCD并行队列[5321:650010] 4-<NSThread: 0x60800007b540>{number = 7, name = (null)}
2017-02-21 22:25:12.607 09-GCD并行队列[5321:649930] 5-<NSThread: 0x60800007b3c0>{number = 4, name = (null)}
2017-02-21 22:25:12.608 09-GCD并行队列[5321:649931] 7-<NSThread: 0x60800007b380>{number = 3, name = (null)}
2017-02-21 22:25:12.608 09-GCD并行队列[5321:650011] 6-<NSThread: 0x600000260e80>{number = 8, name = (null)}
2017-02-21 22:25:12.609 09-GCD并行队列[5321:650012] 8-<NSThread: 0x600000260840>{number = 9, name = (null)}
2017-02-21 22:25:12.609 09-GCD并行队列[5321:649933] 9-<NSThread: 0x60800007b500>{number = 6, name = (null)}
-5.全局队列 + 同步任务 :同-3.

-6.全局队列 + 异步任务 :同-4.

-7.主队列 + 异步任务 : 同-2.

-8.主队列 + 同步任务 : 这里需要注意一个问题,主队列是每次那一个任务出来给主线程执行(此时主线程必须处于空闲状态,如果不空闲,就不能完成任务),但是如果当前线程就是主线程,那么当执行到交给主线程执行任务时,主线程也在等待任务完成,所以一直处在非空闲状态,而任务由于主线程没有处于空闲状态而不被执行,这个时候就产生了矛盾,导致程序崩溃;如果当前线程不是主线程,就同-1.不会产生任何问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值