• 多线程GCD


    经常使用;规避很多线程相关的复杂的逻辑

    为什么会gcd?
    因为pthread和nsthread要求开发人员对线程相关的知识了解深入; 手动启动线程;加锁/解锁;造成很多隐患 --》 苹果公司给出了gcd的多线程的解决方案(可选的设置)

    什么是gcd?
    GCD: Grand Central Dispatch: 一个多线程的解决方案
    dispatch:迅速解决;
    concurrent:同时发生的,并列的;serial:序列的,串行的
     
    特性:
    1) 基于c (宜用);
    2)将原来的子线程做的任务放到队列queue(FIFO)中;以block方式执行
    3) 自动的启动线程来执行队列中的任务(开发人员无需和线程直接打交道)
    4) 线程数gcd会根据当前的资源自动的分配线程个数

    队列类型:
    串行队列:任务一个一个的按照顺序(FIFO)执行; 每次只能执行一个任务,并且必须等待前一个任务执行完毕
    并行队列:同时执行多个任务;不必等待执行任务完成

    执行任务方式:
    同步执行:dispatch_sync队列中的任务在主线程中执行
    异步执行:dispatch_async队列中的任务在子线程中执行
    关键字:dispatch、queue、SERIAL、CONCURRENT
    创建队列:
    //1.创建一个空的串行队列(标题,队列类型[串行、并行])
    DISPATCH_QUEUE_SERIAL = NULL
    dispatch_queue_t queue = dispatch_queue_create("FirstSerialQueue", DISPATCH_QUEUE_SERIAL);
    //1.创建一个空的并行队列
    dispatch_queue_t queue = dispatch_queue_create("FirstConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    执行任务:
    [NSThread currentThread]:获取当前的线程
    [NSThread sleepForTimeInterval:1]:线程延时1秒
    //同步执行
    dispatch_sync(queue, ^{
        //线程执行的任务
        for (int i = 0; i < 10; i++) {
            [NSThread sleepForTimeInterval:1];
            NSLog(@"--------------%@", [NSThread currentThread]);
        }
    });
    //异步执行
    dispatch_async(queue, ^{
        //线程执行的任务
    });
     
    将队列和执行方式组合,就有四种方式:
    -(void)coders{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:1];
            NSLog(@"--------------%@", [NSThread currentThread]);
        }
    }
    //———————————————------—不起作用哪-------------------------------------------
    暂停一个队列
    void dispatch_suspend ( dispatch_object_t object );
    恢复一个队列
    void dispatch_resume ( dispatch_object_t object );
    释放一个队列
    void dispatch_release ( dispatch_object_t object );
    //----------------------------------------------------------------------------
    //组合一:串行+同步:在主线程,按在顺序依次执行:
    - (IBAction)serialSync:(id)sender {
        NSLog(@"串行队列;同步执行");
        //1.创建一个空的串行队列
        dispatch_queue_t queue = dispatch_queue_create("FirstSerialQueue", DISPATCH_QUEUE_SERIAL);
        //2.写第一个任务,并提交
        dispatch_sync(queue, ^{
            //线程执行的任务
            [self coders];
        });
        NSLog(@"打印第一个完毕");
        dispatch_sync(queue, ^{
            //线程执行的任务
            [self coders];
        });
        NSLog(@"打印第二个完毕");
    }
    //组合二:串行+异步:在子线程顺序执行(一个子线程)
    - (IBAction)serialAsync:(id)sender {
        NSLog(@"串行队列;异步执行");
        dispatch_queue_t queue = dispatch_queue_create("SecondSerialQueue", DISPATCH_QUEUE_SERIAL);
        dispatch_async(queue, ^{
            [self coders];
        });
        NSLog(@"打印第一个完毕");
        dispatch_async(queue, ^{
            [self coders];
        });
        NSLog(@"打印第二个完毕");
    }
    //组合三:并行队列+同步执行=没有意义(相对于:串行+同步)
    - (IBAction)concurrentSync:(id)sender {
        NSLog(@"并行队列;同步执行");
        dispatch_queue_t queue = dispatch_queue_create("FirstConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_sync(queue, ^{
            [self coders];
        });
        NSLog(@"打印第一个完毕");
        dispatch_sync(queue, ^{
            [self coders];
        });
        NSLog(@"打印第二个完毕");
    }
    //组合四:并列+异步:在子线程,一个任务对应一个子线程,并列执行
    - (IBAction)concurrentAsync:(id)sender {
        NSLog(@"并行队列;异步执行");
        dispatch_queue_t queue = dispatch_queue_create("SecondConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            [self coders];
        });
        NSLog(@"打印第一个完毕");
        dispatch_async(queue, ^{
            [self coders];
        });
        NSLog(@"打印第二个完毕");
    }
    //----------------------------------------------------------------------------
    队列:
    系统创建好两个的队列:
    主队列(main queue) <—> 串行队列;顺序执行任务
    全局队列(global queue) <—> 并行队列

    排列组合:
    全局队列 +异步执行 <==> 并行队列异步执行,在子线程并行中执行
    主队列 +异步执行    <==> 串行队列异步执行,在主线程顺序中执行
    主队列 + 同步执行     <==> 造成死锁
     
    -(void)coders{
        for (int i = 0; i <2; i++) {
            [NSThread sleepForTimeInterval:1];
            NSLog(@"-------%d-------%@", i,[NSThread currentThread]);
        }
    }
    - (IBAction)golbalSync:(id)sender {
        NSLog(@"全局队列 + 异步");
        //系统默认,直接获取就可以。dispatch_get_global_queue(优先级,)
        dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //2.写第一个任务,并提交
        dispatch_async(globalQueue, ^{
            //线程执行的任务
            [self coders];
        });
        NSLog(@"打印第一个完毕");
        //3.写第二个任务,并提交
        dispatch_async(globalQueue, ^{
            //线程执行的任务
            [self coders];
        });
        NSLog(@"打印第二个完毕");
    }
    主队列+同步:
    - (IBAction)mainSynic:(id)sender {
        NSLog(@"主队列 + 同步");
        //获取主队列,会在主线程中执行队列中的任务
        dispatch_queue_t mainQueue=dispatch_get_main_queue();
        //2.写第一个任务,并提交
        dispatch_async(mainQueue, ^{
            [self coders];
        });
        NSLog(@"打印第一个完毕");
        //3.写第二个任务,并提交
        dispatch_async(mainQueue, ^{
            [self coders];
        });
        NSLog(@"打印第二个完毕");
    }
    主队列(和主线程绑定):顺序执行
    先执行任务一:(mainSync);
    然后再执行任务二:for循环
    //---------------------------------End-------------------------------------------
  • 相关阅读:
    Docker 网络
    Dockerfile你值得拥有
    Spring boot配置成功后,出现Whitelabel Error Page的解决办法
    ubuntu 创建快捷方式
    Ubuntu Make来安装Visual Studio Code
    ubuntu16.04开机自动挂载Windows分区
    ubuntu下使用罗技Unifying
    酷开电视升级后无法启动
    ArcGIS 10.2安装错误,Error: Internal Error 2753. The File is not marked for installation
    ubuntu16.04下使用wine 运行微信开发小程序
  • 原文地址:https://www.cnblogs.com/lignpeng/p/5458311.html
Copyright © 2020-2023  润新知