zoukankan      html  css  js  c++  java
  • GCD线程依赖,GCD队列组,线程监听,线程等待

    1.线程监听

    有时候经常有这样的需求,AB任务都执行完成之后,刷新界面或者执行其他操作,

    /**
     * 队列组 dispatch_group_notify
     */
    - (void)groupNotify {
        NSLog(@"begin");
        
        dispatch_group_t group =  dispatch_group_create();
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务1
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务1---%@",[NSThread currentThread]);      // 打印当前线程
            }
        });
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务2
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务2---%@",[NSThread currentThread]);      // 打印当前线程
            }
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // 等前面的异步任务1、任务2都执行完毕后,回到主线程执行任务
            for (int i = 0; i < 2; ++i) {
                NSLog(@"等待1,2完成后的任务3---%@",[NSThread currentThread]);      // 打印当前线程
            }
            NSLog(@"end");
        });
    }
    

      

    2.线程等待

    暂停当前线程(阻塞当前线程),等待指定的 group 中的任务执行完成后,才会往下继续执行

    从dispatch_group_wait相关代码运行输出结果可以看出:

    当所有任务执行完成之后,才执行 dispatch_group_wait 之后的操作。但是,使用dispatch_group_wait 会阻塞当前线程。

    /**
     * 队列组 dispatch_group_wait
     */
    - (void)groupWait {
    
        NSLog(@"begin");
        
        dispatch_group_t group =  dispatch_group_create();
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务1
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务1---%@",[NSThread currentThread]);      // 打印当前线程
            }
        });
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务2
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务2---%@",[NSThread currentThread]);      // 打印当前线程
            }
        });
        
        // 等待上面的任务全部完成后,会往下继续执行(会阻塞当前线程)
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务3
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务3---%@",[NSThread currentThread]);      // 打印当前线程
            }
        });
      
    }
    

      

    3.延伸阅读

      dispatch_group_async队列组添加任务的方式,是把一个任务添加到队列中,执行完成之后从队列中删除

      dispatch_group_async 也可以用dispatch_async + dispatch_group_enter + dispatch_group_leave的方式

      dispatch_group_enter:标志着一个任务追加到 group,也就是group 中未执行完毕任务数+1
      dispatch_group_leave:正好与前者相反,
    标志着一个任务从group中删除,也就是group 中未执行完毕任务数-1

    当 group 中未执行完毕任务数为0的时候,才会使dispatch_group_wait解除阻塞,以及执行追加到dispatch_group_notify中的任务


    给个例子,打印一下,会更好理解。
    /**
     * 队列组 Enter  Leave
     */
    - (void)groupEnterLeave {
        NSLog(@"begin");
        
        dispatch_group_t group =  dispatch_group_create();
        
        dispatch_group_enter(group);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务1
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务1---%@",[NSThread currentThread]);      // 打印当前线程
            }
            dispatch_group_leave(group);
        });
        
        dispatch_group_enter(group);
        dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务2
            for (int i = 0; i < 2; ++i) {
                NSLog(@"任务2---%@",[NSThread currentThread]);      // 打印当前线程
            }
            dispatch_group_leave(group);
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // 等前面的异步任务1、任务2都执行完毕后,回到主线程执行任务
            for (int i = 0; i < 2; ++i) {
                NSLog(@"等待1,2完成后的任务3---%@",[NSThread currentThread]);      // 打印当前线程
            }
    
            NSLog(@"end");
        });
    }
    

     

      但是如果把上面任务1或者任务2的这句代码注释了dispatch_group_leave(group);

      那么程序就只会执行任务1 2 ,永远不会执行任务3 ,因为只有当 group 中未执行完毕任务数为0的时候,才会使dispatch_group_wait解除阻塞,以及执行追加到dispatch_group_notify中的任务

      注释了之后无论是使用dispatch_group_notify还是dispatch_group_wait,打印的情况都如下

     
     
  • 相关阅读:
    codevs1076 排序
    codevs1075 明明的随机数
    codevs1205 单词翻转
    codevs1204 寻找子串位置
    codevs2235 机票打折
    codevs1206 保留两位小数
    codevs1203 判断浮点数是否相等
    codevs1202 求和
    codevs1201 最小数和最大数
    Static Sushi AtCoder
  • 原文地址:https://www.cnblogs.com/huangzhenwei/p/9728582.html
Copyright © 2011-2022 走看看