GCD

作者: 我爱吃豆芽 | 来源:发表于2016-06-24 15:14 被阅读15次

    1.GCD是最简单的一种多线程,同时也是效率最高的一种方式(全部是用C语言代码编写的API),也是苹果过公司主推的一种多线程方式

    2.GCD通过queue来实现多线程

    3.GCD里面有多种queue一种是串行serial一种是并行concurrent

    pragma mark-------------serial串行队列第一种------------------------

        //serial:第一个任务执行完毕,第二个任务才开始执行,依次类推
        //有两种方式
    //获取主线程
    //    dispatch_queue_t queue = dispatch_get_main_queue();
        //往队列里面添加任务
        
    //    dispatch_async(queue, ^{
    //        NSLog(@"这是第一个任务,当前线程%@,是否主线%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
    //    });
    //    
    //   
    //     dispatch_async(queue, ^{
    //         NSLog(@"这是第二个任务,当前线程%@,是否主线程 %d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    //     });
    //    
    //    
    //    dispatch_async(queue, ^{
    //        NSLog(@"这是第三个任务当前线程%@ ,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    //    });
    //    
    //    dispatch_async(queue, ^{
    //        NSLog(@"这是第四个第四个任务但钱线程%@,是否主线程 %d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    //    });
    

    pragma mark -------------serial串行队列第二种-----------

    /*
         *获取串行队列的第二种方式,自己创建队列。
         
         
            *穿件串行队列的第二种方式
             “serialQueue” 对列的名字 (苹果主推使用反向域名法去命名)
               DISPATCH_QUEUE_SERIAL  队列类型
         
         
              手动创建的串行队列不在主线程中
            */
         
         //dispatch_sync 是主线程 dispatch_async不是主线程
        
        
        dispatch_queue_t queue = dispatch_queue_create("com.serialQueue.www", DISPATCH_QUEUE_SERIAL);
        
        dispatch_async(queue, ^{
            NSLog(@"这是一个任务,当前 线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"这是第二个任务,但钱线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"这是3%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"只是第四个%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        
        dispatch_async(queue, ^{
            NSLog(@"这是5个任务,当前 线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"这是第6个任务,但钱线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"这是7%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"只是第8个%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
    
    

    concurrentQueue 特点:第一个任务执行开始之后,第二个任务不等第一个执行完毕直接开始执行,以此类推,后边的任务跟前面的任务没有关系(先添加的任务不一定先执行,最后添加的任务不一定最后执行),并列队列会根据队列里面的任务数量、cpu、使用情况开辟最合适的线程数量去完成队列里面的任务 创建有两种方式

    pragma mark ------concurrentQueue第一种创建方式-------------

    // 创建并行队列
        
    //global queue 是苹果里面的全局队列,有4个优先级
        
    //   #define DISPATCH_QUEUE_PRIORITY_HIGH 2
    //   #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
    //   #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
    //   #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
    
        
       //第一个参数就是队列的优先级 第二个参数就是苹果预留的参数为了以后使用,目前还没有使
    //    dispatch_queue_t queue = dispatch_queue_create("com.concurrent.www", DISPATCH_QUEUE_CONCURRENT);
    //    
    //    dispatch_async(queue, ^{
    //        NSLog(@"1%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    //    });
    //    
    //    dispatch_async(queue, ^{
    //        NSLog(@"2%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
    //    });
    //    
    //    dispatch_async(queue, ^{
    //        NSLog(@"3%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
    //    });
    //    
    //    dispatch_async(queue, ^{
    //        NSLog(@"4%@ 是否主%d",[NSThread currentThread] ,[[NSThread currentThread] isMainThread]);
    //    });
    
    

    pragma mark ------concurrentQueue第二种创建方式-------------

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^{
            NSLog(@"线程1%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
            
            
        });
        
        dispatch_async(queue, ^{
            NSLog(@"线程2%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        
        dispatch_async(queue, ^{
            NSLog(@"线程3%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"线程4%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"线程5%@ 谁否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
    

    延迟执行代码 (dispatch——after 可以再任何队列中执行,串行并行都可以)

    //第一种
    //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //        NSLog(@"我是延迟执行的代码 线程:%@ 是否是主线程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
    //    });
        
        
        //第二种
        
        dispatch_time_t seconds = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
        //创建一个全局队列
        
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        
         dispatch_after(seconds, queue,^{
             NSLog(@"我是延迟执行的代码%@ 是否主线程%d",[NSThread currentThread],[[NSThread  currentThread]isMainThread ]);
         });
        
    
    

    线程组

    
      //dispatch—Group-t主要是一些不想管的任务归为一组
        //组里面放到是队列
        //dispatch-group-async 作用是给组里面的队列添加任务
        //dispatch-group-notify 作用是坚挺组里面的任务,等到组里面的任务全部执行完成之后,才执行它里面的任务
        
        //第一步创建组
        
        
           dispatch_group_t group = dispatch_group_create();
        
        //创建全局对列
        
        dispatch_queue_t queue = dispatch_queue_create(0, 0);
        
        //往组里面的队列添加任务
        
        dispatch_group_async(group, queue, ^{
            NSLog(@"我是第一个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_group_notify(group, queue, ^{
            NSLog(@"我是最后一个任务,当其他任务完成之后,我再执行  线程%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        
        
        dispatch_group_async(group, queue, ^{
            NSLog(@"我是第三个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_group_async(group, queue, ^{
            NSLog(@"我是第四个%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_group_async(group, queue, ^{
            NSLog(@"我是第五个%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_group_async(hroup, queue, ^{
            NSLog(@"我是第五个%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
    
    
    

    既有数据的写入,也有数据的读取。如何解决该类问题dispatch_barrier_async在它之前的任务可以去并发执行,在它之后的任务也可以并发执行

    dispatch_queue_t  queue =  dispatch_queue_create("com.currentQueue.www", DISPATCH_QUEUE_CONCURRENT);
        
        
        dispatch_async(queue, ^{
            NSLog(@"第一个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
        });
        
        
        dispatch_async(queue, ^{
            NSLog(@"第二个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"第三个任务%@ 是否主线成%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"第四个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        
        dispatch_async(queue, ^{
            NSLog(@"第5个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
            
        });
        
        
        
        dispatch_barrier_async(queue, ^{
            NSLog(@"我正在读取数据,不要来打扰我%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        dispatch_async(queue, ^{
            NSLog(@"第6个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
        
        dispatch_async(queue, ^{
            NSLog(@"第7个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
        });
        
    

    多次执行

     NSArray *array = @[@"1",@"2",@"3"];
        
        dispatch_queue_t queue = dispatch_queue_create(0, 0);
        
        /***
         *多次执行
         *
         *@param  iterations 次数
         *@param  queue      队列
         *
         *@param  size_t     任务
         *
         *
         ***/
        //index 是随机的 是小于次数的随机数
        dispatch_apply(3, queue, ^(size_t index) {
            NSLog(@"%@",array[index]);
        });
    
    

    async 与 sync的区别

     //async 不等block执行完毕,就去执行下面的代码
        //sync 会等block执行完毕只后,才会去执行下面的代码
    
     dispatch_queue_t queue = dispatch_queue_create(0, 0);
    
    dispatch_sync(queue, ^{
             NSLog(@"这是第一个任务");
        });
        NSLog(@"呵呵");
        dispatch_sync(queue, ^{
            NSLog(@"这是第二个任务");
        });
        NSLog(@"哦");
    

    GCD调用函数指针

    
    - (IBAction)functionPointer:(UIButton *)sender {
        
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        
        /***
         *GCD 函数做参数
         *queue 队列
         *contex 函数参数的内容
         *work 函数(函数肚饿返回值必须为void 参数类型必须为 void *)
         ***/
        
        dispatch_async_f(queue, @"呵呵", function);
        
       
        
    }
    
    void function(void *context){
        
        NSLog(@"%@",context);
        printf("哦");
    }
    

    线程互斥

    线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的

    // 1 创建线程锁
        
        NSLock *lock = [[NSLock alloc]init];
        
            _count = 100;//票数
        //创建线程并行队列
        
        dispatch_queue_t queue = dispatch_queue_create("com.sellTicketss.www", DISPATCH_QUEUE_CONCURRENT);
        
        __weak ViewController *weakSelf = self;
        
        for (int i =10; i>0; i--) {
            dispatch_async(queue, ^{
                [lock lock];
                for (int j = 10; j > 0; j--) {
                    NSLog(@"买到了第%d张票",weakSelf.count);
                    weakSelf.count -- ;
                }
                [lock unlock];
            });
        }
    
    

    相关文章

      网友评论

          本文标题:GCD

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