美文网首页
GCD 多线程的使用

GCD 多线程的使用

作者: Coder_XiaoD | 来源:发表于2016-03-07 12:10 被阅读0次

    1.串行队列

    1.1串行队列创建

    dispatch_queue_t queue = dispatch_queue_create("lanou", DISPATCH_QUEUE_SERIAL);

    1.2串行队列的同步执行(不开启多线程)

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

    dispatch_sync(queue, ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

    1.3串行队列的异步执行 (开启多线程 但最多只能开启一条)

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

    dispatch_async(queue, ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    2.并发队列

    2.1并发队列创建

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

    2.2并发队列的同步执行 (不会开启多线程 )

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

    dispatch_sync(queue, ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    2.3并发队列的异步执行 (开启多线程,但编译器不会控制线程的数量,数量由底层线程池决定,开启过多的线程可能会影响系统内存)

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

    dispatch_async(queue, ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    3.主队列

    3.1主队列的创建

    dispatch_queue_t queue = dispatch_get_main_queue();

    3.2主队列的同步执行 (主队列的同步执行会造成主队列和主线程的的互锁  如下面的代码)

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

    dispatch_sync(queue, ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    改善方法 (将其写成block 用并发队列异步执行)

    void (^myBlock)() = ^{

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

    dispatch_sync(queue, ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    };

    dispatch_async(dispatch_queue_create("lanou", DISPATCH_QUEUE_CONCURRENT), myBlock);

    3.3主队列的异步执行(不会开启多线程)

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

    dispatch_async(queue, ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    4.全局队列

    4.1性质

    1.全局队列和并发队列的特性基本一致

    2.并发队列 MRC 必须使用dispatch_release进行释放,而全局队列不用

    3.ARC 都不用进行释放

    4.如果需要使用阻塞的话,必须使用并发队列,下面会进行介绍(第三方框架的话 最好使用并发队列)

    5.全局队列更方便

    4.2全局队列的创建

    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

    4.3全局队列的同步执行(与并发队列一样 不会开启多线程)

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

    dispatch_sync(dispatch_get_global_queue(0, 0), ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    4.4全局队列的异步执行 (与并发队列一样 会开启多线程)

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

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

    NSLog(@"线程为%@ - %d",[NSThread currentThread],i);

    });

    }

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

    5.并发队列同步异步的简单套用使用

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

    void (^task)() = ^{

    dispatch_sync(queue, ^{

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

    });

    dispatch_async(queue, ^{

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

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

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

    });

    dispatch_async(queue, ^{

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

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

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

    });

    };

    dispatch_async(dispatch_get_global_queue(0, 0), task);

    6.阻塞异步(如下面代码 对添加队列进行阻塞,使照片全部下载完毕后 进行添加)

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

    dispatch_async(queue, ^{

    //模拟延时

    [NSThread sleepForTimeInterval:1.0];

    //模拟网络加载

    NSString *fileName = [NSString stringWithFormat:@"%02ld.jpg",index + 1];

    NSString *path = [[NSBundle mainBundle]pathForResource:fileName ofType:nil];

    UIImage *image = [UIImage imageWithContentsOfFile:path];

    //一定要使用自定义的并发队列 如果使用全局队列 无法阻塞队列

    dispatch_barrier_async(queue, ^{

    NSLog(@"添加图片%ld %@",index,[NSThread currentThread]);

    //将图像添加到数组

    [self.pictureList addObject:image];

    });

    NSLog(@"下载完成%@ %@",fileName,[NSThread currentThread]);

    });

    7.一次性执行(一般使用在单例的创建中 dispatch_once 是线程安全的 提示 dispatch_once 内部也是有一把锁 性能很高 苹果推荐)

    +(instancetype)shareDiseaseData{

    static <#类名#> *handler = nil;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    if (!handler) {

    handler = [[<#类名#> alloc]init];

    }

    });

    return handler;

    }

    8.调度组 (创建调度组 将异步任务加载到调度组中,当所有任务完成的时候,调度组可以接受到通知)

    8.1调度组的创建

    dispatch_group_t group = dispatch_group_create();

    8.2调度组的使用

    dispatch_group_async(group, _queue, ^{

    [NSThread sleepForTimeInterval:1];

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

    });

    dispatch_group_async(group, _queue, ^{

    [NSThread sleepForTimeInterval:3];

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

    });

    dispatch_group_async(group, _queue, ^{

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

    });

    8.3调度组通知

    dispatch_group_notify(group, _queue, ^{

    NSLog(@"全部下载完了 %@",[NSThread currentThread]);

    });

    9.GCD还有很多高级的用法,有待更新

    相关文章

      网友评论

          本文标题:GCD 多线程的使用

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