隊列:
在使用GCD的時候,我們會把需要處理的任務(wù)放到Block中,然后將任務(wù)追加到相應(yīng)的隊列里面,這個隊列,叫做Dispatch Queue。然而,存在于兩種Dispatch Queue,一種是要等待上一個執(zhí)行完,再執(zhí)行下一個的Serial Dispatch Queue,這叫做串行隊列;另一種,則是不需要上一個執(zhí)行完,就能執(zhí)行下一個的Concurrent Dispatch Queue,叫做并行隊列。
隊列:可以理解為存放任務(wù)的容器
- 系統(tǒng)標準提供的兩個隊列
// 全局隊列,也是一個并行隊列
dispatch_get_global_queue
// 主隊列,在主線程中運行,因為主線程只有一個,所以這是一個串行隊列
dispatch_get_main_queue - 除此之外,還可以自己生成隊列
// 從DISPATCH_QUEUE_SERIAL看出,這是串行隊列
dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL)
// 同理,這是一個并行隊列
dispatch_queue_create("com.demo.concurrentQueue", DISPATCH_QUEUE_CONCURRENT)
同步與異步
串行與并行針對的是隊列,而同步與異步,針對的則是線程。最大的區(qū)別在于,同步線程要阻塞當前線程,必須要等待同步線程中的任務(wù)執(zhí)行完,返回以后,才能繼續(xù)執(zhí)行下一任務(wù);而異步線程則是不用等待。
同步(sync) 和 異步(async) 的主要區(qū)別在于會不會阻塞當前線程,直到 Block 中的任務(wù)執(zhí)行完畢!
如果是 同步(sync) 操作,它會阻塞當前線程并等待 Block 中的任務(wù)執(zhí)行完畢,然后當前線程才會繼續(xù)往下運行。
如果是 異步(async)操作,當前線程會直接往下執(zhí)行,它不會阻塞當前線程。
GCD跑幾個方法 結(jié)果一目了然
/**
* async -- 并發(fā)隊列(最常用)
* 會不會創(chuàng)建線程:會,一般同時開多條
* 任務(wù)的執(zhí)行方式:并發(fā)執(zhí)行
*/
- (void)asyncGlobalQueue
{
// 獲得全局的并發(fā)隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 將 任務(wù) 添加 全局隊列 中去 異步 執(zhí)行
dispatch_async(queue, ^{
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* sync -- 并發(fā)隊列
* 會不會創(chuàng)建線程:不會,當前線程中執(zhí)行
* 任務(wù)的執(zhí)行方式:串行執(zhí)行
*/
- (void)syncGlobalQueue
{
// 獲得全局的并發(fā)隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 將 任務(wù) 添加 全局隊列 中去 異步 執(zhí)行
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* async -- 串行隊列(有時候用)
* 會不會創(chuàng)建線程:會,一般只開1條線程
* 任務(wù)的執(zhí)行方式:串行執(zhí)行(一個任務(wù)執(zhí)行完畢后再執(zhí)行下一個任務(wù))
*/
- (void)asyncSerialQueue
{
// 1.創(chuàng)建一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
// 2.將任務(wù)添加到串行隊列中 異步 執(zhí)行
dispatch_async(queue, ^{
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* sync 同步執(zhí)行 -- 串行隊列
* 會不會創(chuàng)建線程:不會,當前線程中執(zhí)行
* 任務(wù)的執(zhí)行方式:串行執(zhí)行(一個任務(wù)執(zhí)行完畢后再執(zhí)行下一個任務(wù))
*/
- (void)syncSerialQueue
{
// 1.創(chuàng)建一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
// 2.將任務(wù)添加到串行隊列中 異步 執(zhí)行
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* async 異步執(zhí)行 -- 主隊列串行隊列
* 會不會創(chuàng)建線程:不會,當前線程中執(zhí)行
* 任務(wù)的執(zhí)行方式:串行執(zhí)行(一個任務(wù)執(zhí)行完畢后再執(zhí)行下一個任務(wù))
*/
- (void)asyncMainSerialQueue
{
// 1.創(chuàng)建一個串行隊列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.將任務(wù)添加到串行隊列中 異步 執(zhí)行
dispatch_async(queue, ^{
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載圖片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
/**
* sync 同步執(zhí)行 -- 主隊列串行隊列
* 線程死鎖
*/
- (void)syncMainSerialQueue
{
// 1.創(chuàng)建一個串行隊列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.將任務(wù)添加到串行隊列中 異步 執(zhí)行
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
線程死鎖
- (void)syncSerialQueue
{
// 1.創(chuàng)建一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);
// 2.將任務(wù)添加到串行隊列中 異步 執(zhí)行
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片2---%@", [NSThread currentThread]);
//
dispatch_sync(queue, ^{
NSLog(@"-----XXX下載圖片1XX---%@", [NSThread currentThread]);
});
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載圖片5---%@", [NSThread currentThread]);
});
NSLog(@"-----到底---%@", [NSThread currentThread]);
}
http://www.itdecent.cn/p/c0e2d96a238e
要求請求A和請求B都都完成拿到結(jié)果,再執(zhí)行C操作。
// *** 利用隊列組 ****//
- (void)userGroupMethod
{
// 創(chuàng)建隊列組
dispatch_group_t myGroup = dispatch_group_create();
// 創(chuàng)建并發(fā)隊列
dispatch_queue_t myQueue = dispatch_queue_create(0, 0);
// 使用函數(shù)添加任務(wù)(所有任務(wù)都是并發(fā)執(zhí)行)
/**
* 任務(wù)A
*/
dispatch_group_enter(myGroup);
dispatch_async(myQueue, ^{
// 請求A
if (success) {
// 請求成功
dispatch_group_leave(myGroup);
}else{
// 失敗
dispatch_group_leave(myGroup);
}
});
/**
* 任務(wù)B
*/
dispatch_group_enter(myGroup);
dispatch_async(myQueue, ^{
// 請求B
if (success) {
// 請求成功
dispatch_group_leave(myGroup);
}else{
// 失敗
dispatch_group_leave(myGroup);
}
});
// A,B執(zhí)行完畢,不論成功失敗。只要執(zhí)行完畢就執(zhí)行下方代碼
dispatch_group_notify(myGroup, myQueue, ^{
// 執(zhí)行C操作。注意刷新UI等需要回到主線程。
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新等操作。
});
});
}