美文网首页
多线程总结

多线程总结

作者: 夏末秋刀鱼 | 来源:发表于2017-03-15 15:05 被阅读0次

    之前写的太没营养,推荐个有营养的
    https://www.jianshu.com/p/2d57c72016c6

    情景1.多个网络请求结束再刷新

    1.利用成对的接口请求前dispatch_group_enter、成功或者失败dispatch_group_leave,监听dispatch_group_notify
    2.利用Dispatch Semaphore信号量,先创建dispatch_semaphore_create(0),几个接口就在终点dispatch_semaphore_wait几次,每个接口请求成功或者失败dispatch_semaphore_signal一次
    

    1.任务执行方式:同步执行,异步执行
    任务存放队列方式:串行队列,异步队列

    2.GCD使用:①队列创建或者获取②任务创建添加到队列中

    3.队列的创建和获取

    // 串行队列的创建方法
    dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
    // 并发队列的创建方法
    dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
    //第一个参数表示队列的唯一标识符,用于 DEBUG,可为空。队列的名称推荐使用应用程序 ID 这种逆序全程域名。第二个参数用来识别是串行队列还是并发队列。DISPATCH_QUEUE_SERIAL 表示串行队列,DISPATCH_QUEUE_CONCURRENT 表示并发队列
    
    // 主队列的获取方法
    dispatch_queue_t queue = dispatch_get_main_queue();
    // 全局并发队列的获取方法
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    

    4.任务的创建

    // 同步执行任务创建方法
    dispatch_sync(queue, ^{
        // 这里放同步执行任务代码
    });
    // 异步执行任务创建方法
    dispatch_async(queue, ^{
        // 这里放异步执行任务代码
    });
    

    5.组合


    image.png

    6.异步在并发队列执行任务后,回到主线程刷新

    /**
     * 线程间通信
     */
    - (void)communication {
        // 获取全局并发队列
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        // 获取主队列
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        
        dispatch_async(queue, ^{
            // 异步追加任务 1
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
            
            // 回到主线程
            dispatch_async(mainQueue, ^{
                // 追加在主线程中执行的任务
                [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
                NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
            });
        });
    }
    

    7.GCD 的其他方法
    (栅栏方法:dispatch_barrier_async、延时执行方法:dispatch_after、一次性代码(只执行一次):dispatch_once、快速迭代方法:dispatch_apply、队列组:dispatch_group、信号量:dispatch_semaphore)

    ① 栅栏方法:dispatch_barrier_async

    
     dispatch_async(queue, ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
        });
        
        dispatch_barrier_async(queue, ^{
            // 追加任务 barrier
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"barrier---%@",[NSThread currentThread]);// 打印当前线程
        });
        
        dispatch_async(queue, ^{
            // 追加任务 2
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
        });
    

    同一并发队列,先执行完前面的1个或者多个任务,再执行栅栏中的任务,最后再执行栅栏后一个或者多个任务
    ②延时执行方法:dispatch_after
    ③一次性代码(只执行一次):dispatch_once
    常用语单例初始化的时候
    ④快速迭代方法:dispatch_apply
    异步队列中执行遍历

    /**
     * 快速迭代方法 dispatch_apply
     */
    - (void)apply {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        NSLog(@"apply---begin");
        dispatch_apply(6, queue, ^(size_t index) {
            NSLog(@"%zd---%@",index, [NSThread currentThread]);
        });
        NSLog(@"apply---end");
    }
    

    8.GCD 队列组:dispatch_group
    ①dispatch_group_notify

    /**
     * 队列组 dispatch_group_notify
     */
    - (void)groupNotify {
        NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
        NSLog(@"group---begin");
        
        dispatch_group_t group =  dispatch_group_create();
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
        });
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务 2
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // 等前面的异步任务 1、任务 2 都执行完毕后,回到主线程执行下边任务
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"3---%@",[NSThread currentThread]);      // 打印当前线程
    
            NSLog(@"group---end");
        });
    }
    

    ②dispatch_group_wait

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

    ③dispatch_group_enter、dispatch_group_leave

    /**
     * 队列组 dispatch_group_enter、dispatch_group_leave
     */
    - (void)groupEnterAndLeave {
        NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
        NSLog(@"group---begin");
        
        dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_enter(group);
        dispatch_async(queue, ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
    
            dispatch_group_leave(group);
        });
        
        dispatch_group_enter(group);
        dispatch_async(queue, ^{
            // 追加任务 2
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
            
            dispatch_group_leave(group);
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // 等前面的异步操作都执行完毕后,回到主线程.
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"3---%@",[NSThread currentThread]);      // 打印当前线程
        
            NSLog(@"group---end");
        });
    }
    

    9.Dispatch Semaphore 线程同步(注意注意注意:dispatch_semaphore_create(0)为0,不能为负,否则崩溃)

    /**
     * semaphore 线程同步
     */
    - (void)semaphoreSync {
        
        NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
        NSLog(@"semaphore---begin");
        
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        
        __block int number = 0;
        dispatch_async(queue, ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
            
            number = 100;
            
            dispatch_semaphore_signal(semaphore);
        });
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"semaphore---end,number = %zd",number);
    }
    

    相关文章

      网友评论

          本文标题:多线程总结

          本文链接:https://www.haomeiwen.com/subject/iqwlnttx.html