多线程之GCD(1)

GCD 第一节


1.GCD的优势


1GCD是苹果公司为多核的并行运算提出的解决方案;

(2)GCD会自动利用更多的CPU内核(比如双核、四核);

(3)GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程;

(4)程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码;


2 GCD依赖的库 libdispatch.dylib,每次新建工程的时候,已经自动加载了,无需我们手动添加


3.GCD有2个核心概念


(1)任务:执行的操作;

(2)队列:用来存放任务;

使用步骤:定制任务  ——  确定想做的事情;


将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行;

任务的取出遵循队列的FIFO原则:先进先出,后进后出;


4.GCD中有2个执行任务的函数:


1)用同步的方式执行任务 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

2)用异步的方式执行务 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

      queue:队列  block:任务;把任务放到队列中进行执行;


5. 队列


 (1)并发队列(Concurrent Dispatch Queue)

        可以让多个任务并发执行(自动开启多个线程同时执行任务)并发功能执行在异步函数下才有效;

(2)串行队列 (Serial Dispatch Queue)让任务一个接一个的执行;

  (3)  队列的创建方法


1. 使用dispatch_queue_create函数创建串行队列

     dispatch_queue_t queue = dispatch_queue_create(<#const char *label#>, <#dispatch_queue_attr_t attr#>)

    参数一:

   指定队列的名称,Dispatch Queue 的名称推荐使用应用程序ID,该名称在Xcode和Instruments的调试器中作为Dispatch Queue 的名称表示,同时这  个名称也会出现在应用程序崩溃时所产生的CrashLog中。方便我们进行查找。

   参数二:

   当创建串行队列的时候定义为NULL就可以了,当创建并发队列的时候定义为DISPATCH_QUEUE_CONCURRENT

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

dispatch_queue_t queue =dispatch_queue_create("test18",NULL);

注意:

在对iOS6.0以下的版本,我们需要使用dispatch_release(这里是queue的名称)

对于iOS6.0以上的版本,就不需要使用了

http://blog.csdn.net/yohunl/article/details/17301875


2 使用dispatch_get_global_queue函数获得全局的并发队列 这个是获取的,不需要手动的创建

dispatch_queue_t queue = dispatch_get_global_queue(long identifier, <#unsigned long flags#>)

参数一:

long identifier:ios 8.0 告诉队列执行任务的“服务质量 quality of service”,系统提供的参数有:

#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


参数二:

 unsigned long flags:苹果官方文档是这样解释的: Flags that are reserved for future use。标记是为了未来使用保留的!所以这个参数应该永远指定为0

   如果做ios8.0与ios7.0的适配,可以这样创建全局队列:

  dispatch_queue_t q = dispatch_get_global_queue(0, 0);

   试着用全局队列来做一下异步操作,看看是否为并发执行,如下代码

   dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //获得全局并发队列


 3.使用主队列(跟主线程相关联的队列)主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行

使用dispatch_get_main_queue()获得主队列

dispatch_queue_t queue = dispatch_get_main_queue();


注意:

同步:在当前线程中执行任务,不具备开启新线程的能力;

异步:在新的线程中执行任务,具备开启新线程的能力;

并发:多个任务并发(同时)执行;

串行:一个任务执行完毕后,再执行下一个任务;


6.并发串行队列和同步异步函数组合的结果



同步函数不具备开启线程的能力,无论是什么队列都不会开启线程;


异步函数具备开启线程的能力,开启几条线程由队列决定(串行队列只会开启一条新的线程,并发队列会开启多条线程)。


1,全局并发队列加入到了异步函数中,开启了新的线程,并发执行

- (void)test1{

    dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

    dispatch_async(queue, ^{

        NSLog(@"下载1------%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"下载2------%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"下载3------%@",[NSThreadcurrentThread]);

    });

    NSLog(@"主线程----%@",[NSThreadmainThread]);

    //    2016-03-06 23:09:07.831 GCDDemo[1338:19177]下载2------<NSThread: 0x7f9550f1af00>{number = 3, name = (null)}

    //    2016-03-06 23:09:07.831 GCDDemo[1338:19176]下载1------<NSThread: 0x7f9550d84100>{number = 2, name = (null)}

    //    2016-03-06 23:09:07.831 GCDDemo[1338:19178]下载3------<NSThread: 0x7f9550e23720>{number = 4, name = (null)}

    //    2016-03-06 23:09:07.831 GCDDemo[1338:19054]主线程----<NSThread: 0x7f9550f041c0>{number = 1, name = main}

}


- (void)test12{

    dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

    dispatch_sync(queue, ^{

        NSLog(@"下载1------%@",[NSThreadcurrentThread]);

    });

   

    dispatch_sync(queue, ^{

        NSLog(@"下载2------%@",[NSThreadcurrentThread]);

    });

    

    dispatch_sync(queue, ^{

        NSLog(@"下载3------%@",[NSThreadcurrentThread]);

    });

    

    NSLog(@"主线程----%@",[NSThreadmainThread]);

//    2016-03-06 23:15:36.613 GCDDemo[1522:22205] 下载1------<NSThread: 0x7fd6b1509660>{number = 1, name = main}

//    2016-03-06 23:15:36.613 GCDDemo[1522:22205] 下载2------<NSThread: 0x7fd6b1509660>{number = 1, name = main}

//    2016-03-06 23:15:36.614 GCDDemo[1522:22205] 下载3------<NSThread: 0x7fd6b1509660>{number = 1, name = main}

//    2016-03-06 23:15:36.614 GCDDemo[1522:22205] 主线程----<NSThread: 0x7fd6b1509660>{number = 1, name = main}


}


2.全局并发队列 放到同步函数中没有开启新的线程,串行执行

- (void)test12{

    dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

    dispatch_sync(queue, ^{

        NSLog(@"下载1------%@",[NSThreadcurrentThread]);

    });

   

    dispatch_sync(queue, ^{

        NSLog(@"下载2------%@",[NSThreadcurrentThread]);

    });

    

    dispatch_sync(queue, ^{

        NSLog(@"下载3------%@",[NSThreadcurrentThread]);

    });

    

    NSLog(@"主线程----%@",[NSThreadmainThread]);

//    2016-03-06 23:15:36.613 GCDDemo[1522:22205] 下载1------<NSThread: 0x7fd6b1509660>{number = 1, name = main}

//    2016-03-06 23:15:36.613 GCDDemo[1522:22205] 下载2------<NSThread: 0x7fd6b1509660>{number = 1, name = main}

//    2016-03-06 23:15:36.614 GCDDemo[1522:22205] 下载3------<NSThread: 0x7fd6b1509660>{number = 1, name = main}

//    2016-03-06 23:15:36.614 GCDDemo[1522:22205] 主线程----<NSThread: 0x7fd6b1509660>{number = 1, name = main}


}

3.串行队列在异步函数中 会开启一个线程串行的执行;

- (void)test13{

    

    dispatch_queue_t queue =dispatch_queue_create("queue1",NULL);

    

    dispatch_async(queue, ^{

        NSLog(@"异步函数往串行队列中1----%@",[NSThreadcurrentThread]);

    });

    

    dispatch_async(queue, ^{

        NSLog(@"异步函数往串行队列中2----%@",[NSThreadcurrentThread]);

    });

    

    dispatch_async(queue, ^{

        NSLog(@"异步函数往串行队列中3----%@",[NSThreadcurrentThread]);

    });

    /*

     2016-03-07 22:15:55.689 GCDDemo[1138:18345] 异步函数往串行队列中1----<NSThread: 0x7f88214b1670>{number = 2, name = (null)}

     2016-03-07 22:15:55.689 GCDDemo[1138:18345] 异步函数往串行队列中2----<NSThread: 0x7f88214b1670>{number = 2, name = (null)}

     2016-03-07 22:15:55.690 GCDDemo[1138:18345] 异步函数往串行队列中3----<NSThread: 0x7f88214b1670>{number = 2, name = (null)}

     */   

}


4.串行队列放入到同步函数中会串行执行,不开启新的线程


-(void)test14{

    dispatch_queue_t queue =dispatch_queue_create("patch1",NULL);

    dispatch_sync(queue, ^{

        NSLog(@"同步函数往串行队列1---%@",[NSThreadcurrentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"同步函数往串行队列2---%@",[NSThreadcurrentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"同步函数往串行队列3---%@",[NSThreadcurrentThread]);

    });

    /*

     2016-03-07 22:21:33.219 GCDDemo[1293:20615] 同步函数往串行队列1---<NSThread: 0x7fa3e140ad20>{number = 1, name = main}

     2016-03-07 22:21:33.220 GCDDemo[1293:20615] 同步函数往串行队列2---<NSThread: 0x7fa3e140ad20>{number = 1, name = main}

     2016-03-07 22:21:33.220 GCDDemo[1293:20615] 同步函数往串行队列3---<NSThread: 0x7fa3e140ad20>{number = 1, name = main}

     */

}


5.主线程同步执行,会阻塞线程


-(void)test15{

   //这种方法阻塞了主线程

    dispatch_queue_t queue =dispatch_get_main_queue();

    dispatch_sync(queue, ^{

        NSLog(@"主队列--1%@",[NSThreadcurrentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"主队列--2%@",[NSThreadcurrentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"主队列--3%@",[NSThreadcurrentThread]);

    });

    NSLog(@"主队列--0%@",[NSThreadcurrentThread]);

}


6.主线程在异步函数中,不会开启新的线程,串行的执行;

-(void)test16{

   //这种方法阻塞了主线程

    dispatch_queue_t queue =dispatch_get_main_queue();

    dispatch_async(queue, ^{

        NSLog(@"主队列--1%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"主队列--2%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"主队列--3%@",[NSThreadcurrentThread]);

    });

    NSLog(@"主队列--0%@",[NSThreadcurrentThread]);

    /*

     2016-03-08 10:47:33.020 GCDDemo[1965:36074] 主队列--0<NSThread: 0x7f9b50f032c0>{number = 1, name = main}

     2016-03-08 10:47:33.025 GCDDemo[1965:36074] 主队列--1<NSThread: 0x7f9b50f032c0>{number = 1, name = main}

     2016-03-08 10:47:33.025 GCDDemo[1965:36074] 主队列--2<NSThread: 0x7f9b50f032c0>{number = 1, name = main}

     2016-03-08 10:47:33.026 GCDDemo[1965:36074] 主队列--3<NSThread: 0x7f9b50f032c0>{number = 1, name = main}

     */

}


-(void)test18{

    

    dispatch_queue_t queue =dispatch_queue_create("test18",NULL);

    dispatch_async(queue, ^{

        NSLog(@"test18---1---%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"test18---2---%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"test18---3---%@",[NSThreadcurrentThread]);

    });

   

    /*

     2016-03-14 11:45:04.858 GCDDemo[6083:100657] test18---1---<NSThread: 0x7f9ea052be30>{number = 2, name = (null)}

     2016-03-14 11:45:04.859 GCDDemo[6083:100657] test18---2---<NSThread: 0x7f9ea052be30>{number = 2, name = (null)}

     2016-03-14 11:45:04.860 GCDDemo[6083:100657] test18---3---<NSThread: 0x7f9ea052be30>{number = 2, name = (null)}

     */

}


- (void)test19{

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

    dispatch_async(queue, ^{

        NSLog(@"test19---1---%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"test19---2---%@",[NSThreadcurrentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"test19---3---%@",[NSThreadcurrentThread]);

    });


    /*

     2016-03-14 11:45:04.858 GCDDemo[6083:100659] test19---2---<NSThread: 0x7f9ea070bf00>{number = 3, name = (null)}

     2016-03-14 11:45:04.858 GCDDemo[6083:100658] test19---1---<NSThread: 0x7f9ea0509560>{number = 4, name = (null)}

     2016-03-14 11:45:04.858 GCDDemo[6083:100689] test19---3---<NSThread: 0x7f9ea0709f80>{number = 5, name = (null)}

     */

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值