iOS 多線程

隊列:
在使用GCD的時候,我們會把需要處理的任務(wù)放到Block中,然后將任務(wù)追加到相應(yīng)的隊列里面,這個隊列,叫做Dispatch Queue。然而,存在于兩種Dispatch Queue,一種是要等待上一個執(zhí)行完,再執(zhí)行下一個的Serial Dispatch Queue,這叫做串行隊列;另一種,則是不需要上一個執(zhí)行完,就能執(zhí)行下一個的Concurrent Dispatch Queue,叫做并行隊列。
隊列:可以理解為存放任務(wù)的容器

  1. 系統(tǒng)標準提供的兩個隊列
    // 全局隊列,也是一個并行隊列
    dispatch_get_global_queue
    // 主隊列,在主線程中運行,因為主線程只有一個,所以這是一個串行隊列
    dispatch_get_main_queue
  2. 除此之外,還可以自己生成隊列
    // 從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(), ^{
            // 刷新等操作。
        });

    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 又來到了一個老生常談的問題,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學習操作系統(tǒng)呢? 今天就這個問題開始,來談?wù)劜?..
    tangsl閱讀 4,323評論 0 23
  • 七絕 懶惰 懶惰垂憐薄弱人,勤能補拙健強身。 齊家治國平天下,太久清閑萬事塵。 ~老財神 2017年10月25日
    老財神閱讀 1,022評論 2 9
  • 大地無言 卻廣袤無限 藍天無言 卻蔚藍一片 大海無言 卻能容百川 群山無言 萬壑赴荊門 每個人的心里都有一座斷背山...
    Fwx煙雨傾城閱讀 463評論 0 2

友情鏈接更多精彩內(nèi)容