iOS多线程之GCD - 基础

GCD系列
  • GCD基础
  • GCD进阶函数
  • 调度组dispatch_group
  • 信号量dispatch_semaphore

学习GCD之前,我们需要了解比较重要的几个概念

同步 & 异步

同步:同步就是顺序执行,执行完一个再执行下一个,需要等待、协调运行。
异步:异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。

并发 & 串行

串行:每次只有一个任务被执行。让任务一个接着一个地执行。
并发:多个任务并发(同时)执行。
串行是一次只能执行一个任务,并行是一次能执行多个任务。并行是CPU的多核芯同时执行多个任务 并发是单核CPU交替执行两个任务。

iOS多线程之GCD - 基础_第1张图片
image
队列&任务

iOS多线程之GCD - 基础_第2张图片
image

同步、异步是用来表示线程,并发、串行是用来形容队列的

GCD中的三种队列类型

  1. 主队列串行队列(Main Dispatch Queue)
    使用dispatch_get_main_queue()获得主队列。
  2. 全局并发队列(Global Dispatch Queue)。
    使用dispatch_get_global_queue(long identifier, unsigned long flags)来获取。第一个参数表示优先级,使用DISPATCH_QUEUE_PRIORITY_DEFAULT就行,第二个参数暂时没用,传0
// 主队列的获取方法
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//全局队列的获取方法,第一个参数表示优先级,使用DISPATCH_QUEUE_PRIORITY_DEFAULT就行,第二个参数暂时没用,传0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/*
  1. 自定义串行/并行队列
    使用dispatch_queue_create( )创建
/*
dispatch_queue_create(const char *_Nullable label,
dispatch_queue_attr_t _Nullable attr);
参数说明:
* @param label:队列的唯一标识符,用于 DEBUG,可为空,Dispatch Queue 的名称推荐使用应用程序 ID 这种逆序全程域名
* @param attr:用来标识是串行队列(DISPATCH_QUEUE_SERIAL)还是并发队列(DISPATCH_QUEUE_CONCURRENT)。
* 关于attr文档后面还有一句说明:or the result of a call to a dispatch_queue_attr_make_with_* function,一般不用
*/
//创建串行队列
dispatch_queue_t queue1 = dispatch_queue_create("elaine.yin", DISPATCH_QUEUE_SERIAL);
//创建并发队列
dispatch_queue_t queue2 = dispatch_queue_create("elaine.yin", DISPATCH_QUEUE_CONCURRENT);

GCD队列与执行方式的组合

先来张图镇楼

iOS多线程之GCD - 基础_第3张图片
image

1. 同步+并发
结论:不会开启新线程,任务顺序执行
show the code

#pragma mark - 同步执行 + 并发队列
//同步执行 + 并发队列
- (void)SyncConcurrentTest {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"SyncConcurrent---begin");
    dispatch_queue_t queue = dispatch_queue_create("SyncConcurrent.elaine.yin", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"1:%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"2:%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"3:%@",[NSThread currentThread]);
    });
    NSLog(@"SyncConcurrent---end");
}

image.png

2.异步 + 并发
结论:开启多个线程,异步执行
show the code

#pragma mark - 异步执行 + 并发队列
- (void)AsyncConcurrentTest {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"AsyncConcurrent---begin");
    dispatch_queue_t queue = dispatch_queue_create("AsyncConcurrent.elaine.yin", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1:%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"2:%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"3:%@",[NSThread currentThread]);
    });
    NSLog(@"AsyncConcurrent---end");
}

iOS多线程之GCD - 基础_第4张图片
image.png

3. 同步 + 串行
不开启新线程,任务按照顺序执行
show the code

- (void)SyncSerial {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"SyncSerial---begin");
    dispatch_queue_t queue = dispatch_queue_create("SyncSerial.elaine.yin", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        [NSThread sleepForTimeInterval:1];
        NSLog(@"1:%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:1];
            NSLog(@"2:%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        [NSThread sleepForTimeInterval:3];
        NSLog(@"3:%@",[NSThread currentThread]);
    });
    NSLog(@"SyncSerial---end");
}

iOS多线程之GCD - 基础_第5张图片
image.png

4. 异步 + 串行
结论:开启一个新线程,任务按照顺序执行
show the code

- (void)AsyncSerial {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"AsyncSerial---begin");
    dispatch_queue_t queue = dispatch_queue_create("AsyncSerial.elaine.yin", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1:%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2:%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3:%@",[NSThread currentThread]);
        }
    });
    NSLog(@"AsyncSerial---end");
}

iOS多线程之GCD - 基础_第6张图片
image.png

5. 异步 + 主队列
结论:不开启新线程,任务按照顺序执行
show the code

- (void)AsyncMainQueue {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"AsyncMainQueue---begin");
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1:%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2:%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3:%@",[NSThread currentThread]);
        }
    });
    NSLog(@"AsyncMainQueue---end");
}

iOS多线程之GCD - 基础_第7张图片
image.png

6. 同步 + 主队列
结论:死锁
show the code

- (void)SyncMainQueue {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"SyncMainQueue---begin");
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1:%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2:%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (NSInteger i = 0; i < 2; i ++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3:%@",[NSThread currentThread]);
        }
    });
    NSLog(@"SyncMainQueue---end");
}
iOS多线程之GCD - 基础_第8张图片
image.png

dispatch_suspend(queue) //暂停某个队列 dispatch_suspend挂起指定的dispatch_queue
dispatch_resume(queue) //恢复某个队列 dispatch_resume恢复指定的dispatch_queue

参考链接:
https://www.jianshu.com/p/2d57c72016c6
http://www.cocoachina.com/ios/20161031/17887.html

你可能感兴趣的:(iOS多线程之GCD - 基础)