GCD介紹。串行隊列、並行隊列、全局隊列、主隊列、同步任務、異步任務

GCD:Grand Central Dispath 大中央調度
 
GCD的基本思想就是將操做(任務)放在隊列中去執行
隊列負責調度任務執行所在的線程以及具體的執行時間
隊列的特色是先進先出,新添加至隊列的操做(任務)都會排在隊尾
 
GCD的函數都是以dispatch開頭的,dispatch的意思是「分配、調度」
 
串行隊列中的任務會按順序執行
並行隊列中的任務一般會併發執行,並且沒法肯定任務的執行順序
 
dispatch_async表示異步操做,異步操做會新開闢線程來執行任務,並且沒法肯定任務的執行順序
dispatch_sync表示同步操做,同步操做不會新開闢線程
 
在串行隊列中執行同步任務:不會新建線程,按順序執行任務(毫無用處)
在串行隊列中執行異步任務,會新建線程,按順序執行任務(很是有用)
 
在並行隊列中執行同步任務:不會新建線程,按順序執行任務(幾乎沒用)
在並行隊列中執行異步任務:會新建多個線程,可是沒法肯定任務的執行順序(有用,可是很容易出錯)
 
全局隊列
全局隊列是系統的,直接拿過來就能夠用,與並行隊列相似,可是不能指定隊列的名字,調試時沒法確認任務所在隊列
在全局隊列中執行同步任務:不會新建線程,按順序執行任務
在全局隊列中執行異步任務:會新建多個線程,可是沒法肯定任務的執行順序
 
主隊列
每個應用程序只有一個主線程即只有一個主隊列
爲何須要再主線程上執行任務呢?由於在ios開發中,全部UI的更新任務都必須在主線程上執行。

主隊列中的操做都是在主線程中執行的,不存在異步的概念ios

 

主隊列中添加的同步操做永遠不會被執行(會死鎖)程序員

 

小結:後端

不管什麼隊列和什麼任務,線程的建立和回收不須要程序員參與,由隊列來負責,程序員只須要面對隊列和任務。併發

GCD在後端管理這一個線程池,GCD不只決定着Block代碼塊將在哪一個線程中被執行,異步

並且還能夠根據可用的系統資源對這些線程進行管理,從而讓開發者從線程管理的工做中解放出來,async

經過GCD這種集中的管理線程,緩解了大量的線程被建立的問題。函數

 
 
下面這段代碼是對上述幾種隊列的測試:
 
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
//
// JLViewController.m
// 01-GCD
//
// Created by XinYou on 15-4-3.
// Copyright (c) 2015年 vxinyou. All rights reserved.
//
 
#import "JLViewController.h"
 
@interface JLViewController ()
 
@end
 
@implementation JLViewController
 
- (void)viewDidLoad
{
[super viewDidLoad];
 
// [self GCD_Demo1];
 
// [self GCD_Demo2];
 
// [self GCD_Demo3];
 
[self GCD_Demo4];
}
 
/**
* 主隊列中執行 同步任務 或 異步任務
*/
- (void)GCD_Demo4{
 
// 獲取主隊列
dispatch_queue_t q = dispatch_get_main_queue();
 
// 主隊列中的操做都是在主線程中執行的,不存在異步的概念
// 主隊列中添加的同步操做永遠不會被執行(死鎖),也就是下面這段代碼不會被執行(應該將"dispatch_sync"改成"dispatch_async")
// dispatch_sync(q, ^{
//
// NSLog(@"come here");
// });
 
dispatch_async(q, ^{
 
NSLog(@"come here");
});
}
 
/**
* 全局隊列中執行 同步任務 或 異步任務
*/
- (void)GCD_Demo3{
 
// 獲取全局隊列
// 使用全局隊列不能指定隊列的名稱
// 參數一和參數二都是固定寫法,不要問爲何。
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
/*********************************************************************************/
for (int i = 0; i < 10; ++i) {
 
// dispatch_sync:表示執行同步任務
dispatch_sync(q, ^{
 
NSLog(@"%@---%d", [NSThread currentThread], i);
});
}
/** 打印結果:
{name = (null), num = 1}---0
{name = (null), num = 1}---1
{name = (null), num = 1}---2
{name = (null), num = 1}---3
{name = (null), num = 1}---4
{name = (null), num = 1}---5
{name = (null), num = 1}---6
{name = (null), num = 1}---7
{name = (null), num = 1}---8
{name = (null), num = 1}---9
*/
// num = 1 表示主線程
// 由打印結果可知使用全局隊列執行同步任務,不會新開闢線程,同步任務在主線程中按順序執行。
/*********************************************************************************/
 
/*********************************************************************************/
for (int i = 0; i < 10; ++i) {
 
// dispatch_async:表示執行異步任務
dispatch_async(q, ^{
 
NSLog(@"%@---%d", [NSThread currentThread], i);
});
}
/** 打印結果:
{name = (null), num = 2}—--0
{name = (null), num = 4}—--2
{name = (null), num = 3}—--1
{name = (null), num = 5}—--3
{name = (null), num = 4}—--5
{name = (null), num = 2}—--7
{name = (null), num = 3}—--4
{name = (null), num = 5}—--8
{name = (null), num = 4}—--9
{name = (null), num = 2}—--6
*/
// 由打印結果可知使用全局隊列執行異步任務,會開闢多個子線程,異步任務的執行順序無規律,沒法控制。
/*********************************************************************************/
 
}
 
 
/**
* 並行隊列中執行 同步任務 或 異步任務
*/
- (void)GCD_Demo2{
 
// 建立隊列
// 參數一:指定隊列的名字
// 參數二:隊列的類型,DISPATCH_QUEUE_CONCURRENT表示並行隊列
dispatch_queue_t q = dispatch_queue_create("bing_xing", DISPATCH_QUEUE_CONCURRENT);
 
/*********************************************************************************/
for (int i = 0; i < 10; ++i) {
 
// dispatch_sync:表示執行同步任務
dispatch_sync(q, ^{
 
NSLog(@"%@---%d", [NSThread currentThread], i);
});
}
 
/** 打印結果:
{name = (null), num = 1}---0
{name = (null), num = 1}---1
{name = (null), num = 1}---2
{name = (null), num = 1}---3
{name = (null), num = 1}---4
{name = (null), num = 1}---5
{name = (null), num = 1}---6
{name = (null), num = 1}---7
{name = (null), num = 1}---8
{name = (null), num = 1}---9
*/
// num = 1 表示主線程
// 由打印結果可知使用並行隊列執行同步任務,不會新開闢線程,並行的同步任務在主線程中按順序執行。
/*********************************************************************************/
 
/*********************************************************************************/
for (int i = 0; i < 10; ++i) {
 
// dispatch_async:表示執行異步任務
dispatch_async(q, ^{
 
NSLog(@"%@---%d", [NSThread currentThread], i);
});
}
 
/** 打印結果:
{name = (null), num = 2}—--0
{name = (null), num = 4}—--2
{name = (null), num = 3}—--1
{name = (null), num = 5}—--3
{name = (null), num = 4}—--5
{name = (null), num = 2}—--7
{name = (null), num = 3}—--4
{name = (null), num = 5}—--8
{name = (null), num = 4}—--9
{name = (null), num = 2}—--6
*/
 
// 由打印結果可知使用並行隊列執行異步任務,會開闢多個子線程,並行的異步任務的執行順序無規律,沒法控制。
/*********************************************************************************/
 
 
// 非ARC開發時,千萬別忘記release
// dispatch_release(q);
}
 
 
/**
* 串行隊列中執行 同步任務 或 異步任務
*/
- (void)GCD_Demo1{
 
// 建立隊列
// 參數一:指定隊列的名字
// 參數二:隊列的類型,DISPATCH_QUEUE_SERIAL表示串行隊列
dispatch_queue_t q = dispatch_queue_create("chuan_xing", DISPATCH_QUEUE_SERIAL);
 
/*********************************************************************************/
for (int i = 0; i < 10; ++i) {
 
// dispatch_sync:表示執行同步任務
// dispatch_async:表示執行異步任務
 
dispatch_sync(q, ^{
 
NSLog(@"%@---%d", [NSThread currentThread], i);
});
}
 
/** 打印結果:
{name = (null), num = 1}---0
{name = (null), num = 1}---1
{name = (null), num = 1}---2
{name = (null), num = 1}---3
{name = (null), num = 1}---4
{name = (null), num = 1}---5
{name = (null), num = 1}---6
{name = (null), num = 1}---7
{name = (null), num = 1}---8
{name = (null), num = 1}---9
*/
// num = 1 表示主線程
// 由打印結果可知:使用串行隊列執行同步任務,不會開闢新的線程,這些同步任務是按順序執行的。
// 關於使用串行隊列執行同步任務,開發中極少使用。
/*********************************************************************************/
 
/*********************************************************************************/
for (int i = 0; i < 10; ++i) {
 
// dispatch_async:表示執行異步任務
dispatch_async(q, ^{
 
NSLog(@"%@---%d", [NSThread currentThread], i);
});
}
 
/** 打印結果:
{name = (null), num = 2}—--0
{name = (null), num = 2}—--1
{name = (null), num = 2}—--2
{name = (null), num = 2}—--3
{name = (null), num = 2}—--4
{name = (null), num = 2}—--5
{name = (null), num = 2}—--6
{name = (null), num = 2}—--7
{name = (null), num = 2}—--8
{name = (null), num = 2}—--9
*/
// num = 2 表示子線程
// 由打印結果可知使用串行隊列執行異步任務,會新開闢一個子線程,串行的異步任務在子線程中按順序執行。
// 使用串行隊列執行異步任務,在開發中很是有用!!!
/*********************************************************************************/
 
// 非ARC開發時,千萬別忘記release
// dispatch_release(q);
}
 
@end
相關文章
相關標籤/搜索