GCD的使用

Grand Central Dispatch :牛逼的中枢调度器。

1.优势

最大的优势就是自动,自动利用更多的CPU,自动管理线程的生命周期,不需要任何线程管理代码。

将需要执行的任务添加到队列中,GCD会自动将队列中的人物取出,放到对应的线程中去执行。

遵循原则:FIFO原则:先进先出,后进后出(栈)

2.基本概念

队列:用来存放任务;

并发队列:可以多个任务同时执行(即自动开启多个线程),并发功能只能在异步(dispatch_async)函数下使用

串行队列:任务一个接一个的执行

任务:执行的操作;

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

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

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

串行:只有当前的任务执行完毕后,才能执行下一个任务。

3.任务执行

同步执行:dispatch_sync(参数一:队列 , 参数二:任务);其中任务是一个block

异步执行:dispatch_async(参数一:队列 , 参数二:任务);其中任务是一个block

本质区别:同步在当前的线程中执行,异步是开辟另一条线程去执行任务。

执行步骤:

(1)定制队列、(2)提交任务

4.代码

主队列(串行队列)和全局队列(并发队列):

 1 -(void)mainAndGlobal{
 2 
 3     
 4     // 获取主队列,串行队列
 5     dispatch_queue_t main_queue = dispatch_get_main_queue();
 6     
 7     // 获取全局队列,并发队列
 8     dispatch_queue_t global_queue = dispatch_get_global_queue(0, 0);
 9     
10     /*dispatch_get_global_queue(long identifier, 0)
11      参数一:全局队列的优先级
12      #define DISPATCH_QUEUE_PRIORITY_HIGH 2
13      #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
14      #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
15      #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
16      参数二:并没有什么~用
17      */
18     
19     //1.向全局队列中提交异步任务(开辟子线程去执行任务)
20     dispatch_async(global_queue, ^{
21         
22         NSLog(@"1.向并发队列中提交异步任务--%@",[NSThread currentThread]);
23     });
24     dispatch_async(global_queue, ^{
25         
26         NSLog(@"2.向并发队列中提交异步任务--%@",[NSThread currentThread]);
27     });
28     
29     //2.向主队列中提交异步任务(在当前的线程中执行任务,且任务发生在当前线程的所有任务执行完毕后)
30     dispatch_async(main_queue, ^{
31         
32         NSLog(@"1.向串行队列中提交异步任务--%@",[NSThread currentThread]);
33     });
34     dispatch_async(main_queue, ^{
35         
36         NSLog(@"2.向串行队列中提交异步任务--%@",[NSThread currentThread]);
37     });
38     
39     //3.向全局队列中提交同步任务(任务发生在当前线程)
40     dispatch_sync(global_queue, ^{
41         
42         NSLog(@"1.向并发队列中提交同步任务--%@",[NSThread currentThread]);
43     });
44     dispatch_sync(global_queue, ^{
45         
46         NSLog(@"2.向并发队列中提交同步任务--%@",[NSThread currentThread]);
47     });
48     
49 //    4.向主队列中提交同步任务(造成线程的死锁,需要避免的情况)
50         dispatch_sync(main_queue, ^{
51     
52             NSLog(@"1.向串行队列中提交同步任务--%@",[NSThread currentThread]);
53         });
54         dispatch_sync(main_queue, ^{
55     
56             NSLog(@"2.向串行队列中提交同步任务--%@",[NSThread currentThread]);
57         });
58     
59     /*
60      
66 }
总结:
1.只要是同步任务,任务都是在当前的线程中执行,不开辟子线程,所以会阻塞当前线程只有当前任务完成后才能去执行下一个任务,所以要避免死循环。 2.异步任务在全局队列中才能开辟子线程,在主线程中不开辟子线程 3.同步任务不能添加到主队列中,会造成线程死锁。

创建队列:

 1 /*
 2      dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)
 3      参数一:char型指针
 4      参数二:指定队列的类型
 5      DISPATCH_QUEUE_SERIAL:串行
 6      DISPATCH_QUEUE_CONCURRENT:并发
 7      */
 8     
 9     dispatch_queue_t serial_q = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
10 
11     dispatch_queue_t concurrent_q = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);

提交任务代码同上,需要注意的是:

 1     //向串行队列中提交同步任务(会造成死锁)
 2     dispatch_sync(serial_q, ^{
 3 
 4         NSLog(@"3.向串行队列中提交同步任务--%@",[NSThread currentThread]);
 5         
 6         dispatch_sync(serial_q, ^{
 7             
 8             NSLog(@"4.向串行队列中提交同步任务--%@",[NSThread currentThread]);
 9         });
10         
11     });
12 
13 //此种情况不会造成死锁
14 dispatch_sync(serial_q, ^{
15             
16             NSLog(@"3.向串行队列中提交同步任务--%@",[NSThread currentThread]);
17         });
18 
19 dispatch_sync(serial_q, ^{
20             
21             NSLog(@"4.向串行队列中提交同步任务--%@",[NSThread currentThread]);
22         });

总结:在一个串行队列执行的代码中,如果向此队列同步提交一个任务,会造成死锁。这就要求要避免在串行队列中同步提交任务给本身的队列。

 

 

posted @ 2016-03-23 16:12  C_David  阅读(407)  评论(0编辑  收藏  举报