多线程 GCD 的使用

时间:2022-08-08 05:15:34

参考:http://www.jianshu.com/p/2d57c72016c6

GCD 的两个核心概念: 队列 与 任务

一.队列

  队列分为串行队列和并发队列, 队列的作用是管理开发者提交的任务,在队列的底层维护了一个线程池,用于执行任务

  串行队列底层的线程池, 只维护一个线程

  并发队列底层的线程池, 可以维护多个线程

二.任务

  任务分为 同步任务 和 异步任务,主要区别是 是否具备开启新线程的能力

综上,只有将 异步任务 添加到 并发队列中,才可以达到并发执行任务的目的(队列满足: 能够维护多个线程  任务满足: 具备开启新线程的能力),其他组合不能满足这两个条件

三. GCD 的函数 使用

//基本创建

- (void)baseCreate{

    //队列的创建

    //串行队列(主队列)

    dispatch_queue_t queueSer = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);

    //并发队列(全局队列)

    dispatch_queue_t queueCon = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);

    

    

    //任务的创建

    //同步任务+串行

    dispatch_sync( queueSer, ^{

        NSLog(@"%@",[NSThread currentThread]);

        

    });

    //异步任务+并发

    dispatch_async(queueCon, ^{

        NSLog(@"%@",[NSThread currentThread]);

        

    });

    

}

 

#pragma mark  同步任务+并发队列

- (void)syncConcurrent

{

    NSLog(@"syncConcurrent---begin");

    

    dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);

    

    dispatch_sync(queue, ^{

        for (int i = 0; i < 2; ++i) {

            NSLog(@"1------%@",[NSThread currentThread]);

        }

    });

    dispatch_sync(queue, ^{

        for (int i = 0; i < 2; ++i) {

            NSLog(@"2------%@",[NSThread currentThread]);

        }

    });

    dispatch_sync(queue, ^{

        for (int i = 0; i < 2; ++i) {

            NSLog(@"3------%@",[NSThread currentThread]);

        }

    });

    

    NSLog(@"syncConcurrent---end");

}

 

#pragma mark  异步任务+并发队列

- (void)asyncConcurrent

{

    NSLog(@"asyncConcurrent---begin");

    

    dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);

    

    dispatch_async(queue, ^{

        for (int i = 0; i < 2; ++i) {

            NSLog(@"1------%@",[NSThread currentThread]);

        }

    });

    dispatch_async(queue, ^{

        for (int i = 0; i < 2; ++i) {

            NSLog(@"2------%@",[NSThread currentThread]);

        }

    });

    dispatch_async(queue, ^{

        for (int i = 0; i < 2; ++i) {

            NSLog(@"3------%@",[NSThread currentThread]);

        }

    });

    

    NSLog(@"asyncConcurrent---end");

}

//栅栏

- (void)barrier

{

    dispatch_queue_t queue = dispatch_queue_create("12312312", DISPATCH_QUEUE_CONCURRENT);

    

    dispatch_async(queue, ^{

        NSLog(@"----1-----%@", [NSThread currentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"----2-----%@", [NSThread currentThread]);

    });

    //栅栏的作用: 必须前面的任务执行完成之后,才会执行后面的任务

    dispatch_barrier_async(queue, ^{

        NSLog(@"----barrier-----%@", [NSThread currentThread]);

    });

    

    dispatch_async(queue, ^{

        NSLog(@"----3-----%@", [NSThread currentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"----4-----%@", [NSThread currentThread]);

    });

}

 

//延迟执行

- (void)after{

    //after 延迟执行,并不会阻塞主队列

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

        NSLog(@"1 after--%@",[NSDate date]  );

    });

}

 

 

//多次执行该段代码

- (void)apply{

    //同一时间--执行该段代码 n

    dispatch_apply(500, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {

        NSLog(@"apply%@",[NSDate date]);

    });

    

}

 

 

//队列组

//将对个任务添加到队列组中, 需要多个任务都执行完成后,在做其他操作(回到主线程刷新 UI)

- (void)group{

    //1.将任务添加到队列组中

    dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"----1-----%@", [NSThread currentThread]);

 

    });

    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"----2-----%@", [NSThread currentThread]);

        

    });

    

    //2.调用队列组的通知方法,监听任务都执行完毕-->其他线程

    dispatch_group_notify(group,  dispatch_get_main_queue(), ^{

        NSLog(@"main--刷新 UI");

    });

    

    

    

}

 

关于多线程死锁问题:(造成任务一直等待,不能向下执行)

参考:http://www.cnblogs.com/Twisted-Fate/p/4864278.html