GCD

 

GCD

简述

串行队列: 顺序, 一个一个执行. 并发对列: 可以同时把很多任务取出来, 有线程就执行. 同步任务: 不会开辟新的线程, 在当前线程中执行. 异步会开辟新的线程 串行队列每次只会拿出一个任务执行, 因此串行异步任务最多只会创建两个线程(即子线程和主线程).

串行并行针对于队列而言, 同步异步针对于线程而言.

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

同步: 当前线程中执行, 不具备开启新线程的能力. 但会马上执行

异步: 在新的线程中执行, 具备开启线程的能力. 但不会立即执行

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

并发: 多个任务并发/同时执行

串行: 一个任务执行完, 再执行另外一个任务.

串行/并行描述的是处理任务的速度问题

同步/异步描述的是处理任务的先后顺序问题

主队列: dispatch_get_main_queue()

同步任务, 立刻执行

异步队列, 只是添加到主队列, 但不会立即执行.

在主队列中, 异步添加10人任务. 执行的顺序: 主队列先执行-然后才是添加到主队列的10个任务再执行.

在主队列中, 同步添加10个任务. 执行的顺序: 会卡死. 因为同步队列立刻执行. 但这个时候主队列的任务正在执行. 主队列执行完之后才会执行同步任务, 因此等待同步任务执行完毕; 同步任务立刻执行, 同步任务执行完毕之后才会执行主队列. 双方都等待资源的释放, 因此卡死.

全局队列的本质就是并发队列, 但他是系统的.

全局队列和并发队列的区别: 调度任务的方式相同

  1. 全局队列没有名称, 并发队列有名称.
  2. 全局队列可以供所有的应用程序共享

队列的选择:

串行队列异步执行: 开一条线程, 顺序执行, 效率不高,占用资源少. 并发任务异步执行: 效率高, 占用资源大.

线程间通信: 在子线程中下载图片, 然后强制在主线程中更新图片.

dispatch_async(dispatch_get_global_queue(0,0), ^{

    NSURL *url = [NSURLURLWithString:@"https://ss2.baidu.com/-vo3dSag_xI4khGko9WTAnF6hhy/super/whfpf%3D425%2C260%2C50/sign=a4b3d7085dee3d6d2293d48b252b5910/0e2442a7d933c89524cd5cd4d51373f0830200ea.jpg"];
    NSData *data = [NSDatadataWithContentsOfURL:url];
    UIImage *image = [UIImageimageWithData:data];

    // 在主线程跟新UI
    dispatch_async(dispatch_get_main_queue(), ^{

        self.imageview.image = image;
    });
});

线程调度组, 线程依赖

// 实际开发中,有时候在多个网路请求完成以后,需要统一的通知用户

dispatch_group_t group =dispatch_group_create();
dispatch_queue_t queue =dispatch_get_global_queue(0,0);

dispatch_group_async(group, queue, ^{

    NSLog(@"1111111111111111111111111111111111111111");
});

dispatch_group_async(group, queue, ^{

    NSLog(@"22222222222222222222222222222222222222222222");
});

dispatch_group_async(group, queue, ^{

    NSLog(@"33333333333333333333333333333333333333333333");
});

dispatch_group_notify(group,dispatch_get_main_queue(), ^{

    NSLog(@"========通知我执行完了===========");
});
* 好几个任务执行完之后, 统一做一件事

// group表示要等待的组,DISPATCH_TIME_NOW表示等待的时间.返回值表示要等待的时间: 0这个组已经执行完, 非0未执行完

dispatch_group_wait(group, DISPATCH_TIME_NOW);// 立即检查

dispatch_group_wait(group,DISPATCH_TIME_FOREVER);// 一直等到这个组的任务执行完, 此模式会阻塞

dispatch_suspend(queue);// 线程挂起和恢复 dispatch_resume(queue);

GCD延时方法

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

});

GCD只执行一次的方法

dispatch_once_t onceTocken;
dispatch_once(&onceTocken, ^{

    NSLog(@"===%ld", onceTocken);
});

dispatch_sync(dispatch_get_main_queue(), ^{// 在主线程中执行这个方法会死锁 NSLog(@"xxx"); });

防止数据竞争 : 使用 dispatch_barrier_async 方法

dispatch_async(queue, block1_for_reading)

dispatch_async(queue, block2_for_reading)

dispatch_barrier_async(queue, block_for_writing)

dispatch_async(queue, block3_for_reading)

dispatch_async(queue, block4_for_reading)信号量

死锁问题

NSLog(@"1");

dispatch_async(dispatch_get_main_queue(), ^{

        NSLog(@"2");

});

NSLog(@"3");

队列中 有任务1在执行,这时候添加任务2到队列中. 主队列中的任务串行执行(任务1执行完之后,任务2才能执行,但任务2不执行完,任务1完成不了。任务1完成不了,任务2没法开始)

信号量

dispatch_semaphore_create(2) // 创建信号量

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER) // 加锁

dispatch_semaphore_signal(semaphore) // 解锁

工作中线程组和信号量的使用的应用

    • 使用AFNetwork异步请求好几个任务全部结束之后, 统一做一件事
     dispatch_group_t group =dispatch_group_create();
    
        dispatch_group_enter(group);
        //---------使用AFNetwork请求数据-------------
        dispatch_group_leave(group);
    
        dispatch_group_enter(group);
        //---------使用AFNetwork请求数据-------------
        dispatch_group_leave(group);
    
        dispatch_group_enter(group);
        //---------使用AFNetwork请求数据-------------
        dispatch_group_leave(group);
    
        dispatch_group_notify(group,dispatch_get_main_queue(), ^{
    
            // ...
        });
    
  1. 信号量

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
    
        dispatch_semaphore_t sem = dispatch_semaphore_create(0);
        NSDictionary *dict = @{@"username" : @"23716997892", @"password" : @"123123", @"type" : @"1"};
        [HTRequestHelper LoginDataParams:dict success:^(id responseObj) {
    
            NSLog(@"1111111111111111");
            dispatch_semaphore_signal(sem);
        } failure:^(NSError *error) {
    
            dispatch_semaphore_signal(sem);
        }];
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
    
        dispatch_semaphore_t sem = dispatch_semaphore_create(0);
        [HTRequestHelper RefreshDataSuccess:^(id responseObj) {
    
            NSLog(@"2222222222222");
            dispatch_semaphore_signal(sem);
        } failure:^(NSError *error) {
    
            dispatch_semaphore_signal(sem);
        }];
    
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"3333333333333");
    });

     

     

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值