GCD

2016-06-24  本文已影响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];
        });
    }

上一篇下一篇

猜你喜欢

热点阅读