ios-day19-02(GCD介绍。串行队列、并行队列、全局队列、主队列、同步任务、异步任务)


GCD:Grand Central Dispath 大中央调度

GCD的基本思想就是将操作(任务)放在队列中去执行
队列负责调度任务执行所在的线程以及具体的执行时间
队列的特点是先进先出,新添加至队列的操作(任务)都会排在队尾

GCD的函数都是以dispatch开头的,dispatch的意思是“分配、调度”

串行队列中的任务会按顺序执行
并行队列中的任务通常会并发执行,而且无法确定任务的执行顺序

dispatch_async表示异步操作,异步操作会新开辟线程来执行任务,而且无法确定任务的执行顺序
dispatch_sync表示同步操作,同步操作不会新开辟线程

在串行队列中执行同步任务:不会新建线程,按顺序执行任务(毫无用处)
在串行队列中执行异步任务,会新建线程,按顺序执行任务(非常有用)

在并行队列中执行同步任务:不会新建线程,按顺序执行任务(几乎没用)
在并行队列中执行异步任务:会新建多个线程,但是无法确定任务的执行顺序(有用,但是很容易出错)

全局队列
全局队列是系统的,直接拿过来就可以用,与并行队列类似,但是不能指定队列的名字,调试时无法确认任务所在队列
在全局队列中执行同步任务:不会新建线程,按顺序执行任务
在全局队列中执行异步任务:会新建多个线程,但是无法确定任务的执行顺序

主队列
每一个应用程序只有一个主线程即只有一个主队列
为什么需要再主线程上执行任务呢?因为在ios开发中,所有UI的更新任务都必须在主线程上执行

主队列中的操作都是在主线程中执行的,不存在异步的概念

主队列中添加的同步操作永远不会被执行(会死锁)


小结:

无论什么队列和什么任务,线程的创建和回收不需要程序员参与,由队列来负责,程序员只需要面对队列和任务

GCD在后端管理这一个线程池,GCD不仅决定着Block代码块将在哪个线程中被执行,

而且还可以根据可用的系统资源对这些线程进行管理,从而让开发者从线程管理的工作中解放出来,

通过GCD这种集中的管理线程,缓解了大量的线程被创建的问题。



下面这段代码是对上述几种队列的测试:

//
//  JLViewController.m
//  01-GCD
//
//  Created by XinYou on 15-4-3.
//  Copyright (c) 2015年 vxinyou. All rights reserved.
//

#import "JLViewController.h"

@interface JLViewController ()

@end

@implementation JLViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
//    [self GCD_Demo1];

//    [self GCD_Demo2];

//    [self GCD_Demo3];
    
    [self GCD_Demo4];
}

/**
 *  主队列中执行 同步任务 或 异步任务
 */
- (void)GCD_Demo4{

    // 获取主队列
    dispatch_queue_t q = dispatch_get_main_queue();
    
    // 主队列中的操作都是在主线程中执行的,不存在异步的概念
    // 主队列中添加的同步操作永远不会被执行(死锁),也就是下面这段代码不会被执行(应该将"dispatch_sync"改为"dispatch_async")
//    dispatch_sync(q, ^{
//        
//        NSLog(@"come here");
//    });
    
    dispatch_async(q, ^{

        NSLog(@"come here");
    });
}

/**
 *  全局队列中执行 同步任务 或 异步任务
 */
- (void)GCD_Demo3{

    // 获取全局队列
    // 使用全局队列不能指定队列的名称
    // 参数一和参数二都是固定写法,不要问为什么。
    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    /*********************************************************************************/
    for (int i = 0; i < 10; ++i) {
        
        // dispatch_sync:表示执行同步任务
        dispatch_sync(q, ^{
            
            NSLog(@"%@---%d", [NSThread currentThread], i);
        });
    }
    /** 打印结果:
     {name = (null), num = 1}---0
     {name = (null), num = 1}---1
     {name = (null), num = 1}---2
     {name = (null), num = 1}---3
     {name = (null), num = 1}---4
     {name = (null), num = 1}---5
     {name = (null), num = 1}---6
     {name = (null), num = 1}---7
     {name = (null), num = 1}---8
     {name = (null), num = 1}---9
     */
    // num = 1 表示主线程
    // 由打印结果可知使用全局队列执行同步任务,不会新开辟线程,同步任务在主线程中按顺序执行。
    /*********************************************************************************/
    
    /*********************************************************************************/
    for (int i = 0; i < 10; ++i) {
        
        // dispatch_async:表示执行异步任务
        dispatch_async(q, ^{
            
            NSLog(@"%@---%d", [NSThread currentThread], i);
        });
    }
    /** 打印结果:
     {name = (null), num = 2}—--0
     {name = (null), num = 4}—--2
     {name = (null), num = 3}—--1
     {name = (null), num = 5}—--3
     {name = (null), num = 4}—--5
     {name = (null), num = 2}—--7
     {name = (null), num = 3}—--4
     {name = (null), num = 5}—--8
     {name = (null), num = 4}—--9
     {name = (null), num = 2}—--6
     */
    // 由打印结果可知使用全局队列执行异步任务,会开辟多个子线程,异步任务的执行顺序无规律,无法控制。
    /*********************************************************************************/
    
}


/**
 *  并行队列中执行 同步任务 或 异步任务
 */
- (void)GCD_Demo2{
    
    // 创建队列
    // 参数一:指定队列的名字
    // 参数二:队列的类型,DISPATCH_QUEUE_CONCURRENT表示并行队列
    dispatch_queue_t q = dispatch_queue_create("bing_xing", DISPATCH_QUEUE_CONCURRENT);
    
    /*********************************************************************************/
    for (int i = 0; i < 10; ++i) {
        
        // dispatch_sync:表示执行同步任务
        dispatch_sync(q, ^{
            
            NSLog(@"%@---%d", [NSThread currentThread], i);
        });
    }
    
    /** 打印结果:
     {name = (null), num = 1}---0
     {name = (null), num = 1}---1
     {name = (null), num = 1}---2
     {name = (null), num = 1}---3
     {name = (null), num = 1}---4
     {name = (null), num = 1}---5
     {name = (null), num = 1}---6
     {name = (null), num = 1}---7
     {name = (null), num = 1}---8
     {name = (null), num = 1}---9
     */
    // num = 1 表示主线程
    // 由打印结果可知使用并行队列执行同步任务,不会新开辟线程,并行的同步任务在主线程中按顺序执行。
    /*********************************************************************************/
    
    /*********************************************************************************/
    for (int i = 0; i < 10; ++i) {
        
        // dispatch_async:表示执行异步任务
        dispatch_async(q, ^{
            
            NSLog(@"%@---%d", [NSThread currentThread], i);
        });
    }
    
    /** 打印结果:
     {name = (null), num = 2}—--0
     {name = (null), num = 4}—--2
     {name = (null), num = 3}—--1
     {name = (null), num = 5}—--3
     {name = (null), num = 4}—--5
     {name = (null), num = 2}—--7
     {name = (null), num = 3}—--4
     {name = (null), num = 5}—--8
     {name = (null), num = 4}—--9
     {name = (null), num = 2}—--6
     */
    
    // 由打印结果可知使用并行队列执行异步任务,会开辟多个子线程,并行的异步任务的执行顺序无规律,无法控制。
    /*********************************************************************************/
    
    
    // 非ARC开发时,千万别忘记release
//    dispatch_release(q);
}


/**
 *  串行队列中执行 同步任务 或 异步任务
 */
- (void)GCD_Demo1{
    
    // 创建队列
    // 参数一:指定队列的名字
    // 参数二:队列的类型,DISPATCH_QUEUE_SERIAL表示串行队列
    dispatch_queue_t q = dispatch_queue_create("chuan_xing", DISPATCH_QUEUE_SERIAL);
    
    /*********************************************************************************/
    for (int i = 0; i < 10; ++i) {
        
        // dispatch_sync:表示执行同步任务
        // dispatch_async:表示执行异步任务
        
        dispatch_sync(q, ^{
            
            NSLog(@"%@---%d", [NSThread currentThread], i);
        });
    }
    
    /** 打印结果:
     {name = (null), num = 1}---0
     {name = (null), num = 1}---1
     {name = (null), num = 1}---2
     {name = (null), num = 1}---3
     {name = (null), num = 1}---4
     {name = (null), num = 1}---5
     {name = (null), num = 1}---6
     {name = (null), num = 1}---7
     {name = (null), num = 1}---8
     {name = (null), num = 1}---9
     */
    // num = 1 表示主线程
    // 由打印结果可知:使用串行队列执行同步任务,不会开辟新的线程,这些同步任务是按顺序执行的。
    // 关于使用串行队列执行同步任务,开发中极少使用。
    /*********************************************************************************/
    
    /*********************************************************************************/
    for (int i = 0; i < 10; ++i) {
        
        // dispatch_async:表示执行异步任务
        dispatch_async(q, ^{
            
            NSLog(@"%@---%d", [NSThread currentThread], i);
        });
    }
    
    /** 打印结果:
     {name = (null), num = 2}—--0
     {name = (null), num = 2}—--1
     {name = (null), num = 2}—--2
     {name = (null), num = 2}—--3
     {name = (null), num = 2}—--4
     {name = (null), num = 2}—--5
     {name = (null), num = 2}—--6
     {name = (null), num = 2}—--7
     {name = (null), num = 2}—--8
     {name = (null), num = 2}—--9
     */
    // num = 2 表示子线程
    // 由打印结果可知使用串行队列执行异步任务,会新开辟一个子线程,串行的异步任务在子线程中按顺序执行。
    // 使用串行队列执行异步任务,在开发中非常有用!!!
    /*********************************************************************************/
    
    // 非ARC开发时,千万别忘记release
//    dispatch_release(q);
}

@end
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值