iOS 開發過程中,常常需要用到多線程技術,GCD 是常用的實作多線程的技術,其因簡潔底層而備受歡迎。
GCD 技術中,同步(synchronization)\ 異步(asynchronization),串行(serial)\ 并行(concurrency)等概念常常令人迷惑,不好了解。本文将對這兩對概念進行盡可能簡單的闡釋。
同步和異步是針對目前代碼流(即目前線程)和加入隊列中的任務之間執行順序的關系而言的。以同步的方式向隊列中添加任務會阻塞目前線程,直到同步到隊列中的任務執行完畢傳回後,才會接着執行目前的代碼流;以異步的方式向隊列中添加的任務則不會阻塞目前線程,将任務添加到隊列中後,不用等待任務執行完畢,即刻執行目前代碼流。舉例說明如下:
同步(dispatch_sync):
上面的代碼執行結果隻有一種可能,即輸出“1234”。
在将輸出 1 的任務(即代碼中任務 1)同步到隊列 myQueue 中後,目前線程阻塞,等待任務 1 執行完畢并傳回後(即輸出 1 之後),才能接着執行目前線程,輸出 2。輸出 2 之後,目前代碼流繼續運作,将任務 3 再同步到隊列 myQueue 中後,目前線程阻塞,等待任務 3 執行,輸出 3,之後目前代碼流繼續運作輸出 4。
這段代碼的輸出結果與 myQueue 是串行隊列還是并行隊列沒有關系。
異步(dispatch_async):
上面代碼執行結果可能為 “1234”、“1243”、“2134”、“2143”、“2413” 中的一種,2 始終在 4 前面,1 始終在 3 前面(注意:此例中的隊列(serialQueue)為串行隊列,串行隊列的概念将在後文講述),2 始終在 3 前面。
将任務 1 異步添加到隊列 serialQueue 中之後,不需要等待其執行完畢,目前代碼流就繼續執行了。目前代碼流輸出 2 時,可能任務 1 還沒執行,也可能執行完畢了,是以 1 可能在 2 前輸出也可能在 2 後輸出;
同理,将任務 3 異步添加到隊列 serialQueue 中之後,不需要等待其執行完畢,目前代碼流就繼續執行。目前代碼流輸出 4 時,可能任務 3 還沒執行,也可能執行完畢了,是以 3 可能在 4 前輸出也可能在 4 後輸出。
對于目前代碼流,輸出 2 一定在 輸出 4 前執行,是以 2 必定在 4 前輸出。
對于串行隊列 serialQueue ,任務 1 一定在 任務 3 前執行,是以 1 必定在 3 前輸出。
将任務 3 添加到隊列 serialQueue 的操作必定在輸出 2 後進行,是以 2 必定在 3 前輸出。
串行和并行是針對一個隊列中的多個任務執行順序而言的。串行隊列是指隊列中的任務是一個接一個地執行的,隊首的任務執行完畢後才能執行其後面的任務,直至執行隊尾的任務;并行隊列是指隊列中的任務可以并發地執行,即開始執行隊首的任務後,不必等其執行完畢就可以接着開始執行隊首之後的任務,是以在某一時刻可能存在同時執行的多個任務。
建立串行隊列的方法是:
或
同時主線程的隊列也是串行隊列,擷取方法:
建立并行隊列的方法是:
同時系統提供了擷取系統并發隊列的函數:
第一個參數 identifier 的值宏定義可以為
DISPATCH_QUEUE_PRIORITY_HIGH、
DISPATCH_QUEUE_PRIORITY_DEFAULT、
DISPATCH_QUEUE_PRIORITY_LOW、
DISPATCH_QUEUE_PRIORITY_BACKGROUND,
四個參數值擷取的并發隊列優先級依次從高到低;第二個參數 flags為系統保留參數,應傳入值 0。
混淆同步異步和并行串行的概念,是因為我們沒有弄清楚它們分别針對的對象是什麼,一旦明白了它們描述的對象的差別,就不會在混淆了。再次總結一下,同步異步描述的是目前線程或代碼流是否要阻塞以等待加入隊列的任務執行完畢:同步要阻塞目前線程;異步不會阻塞目前線程。串行和并行描述的時隊列裡各個任務是否可以并發執行:串行隊列裡的任務不能并發執行,隻能一個接一個地執行,同一時刻該串行隊列裡的任務最多隻有一個在執行;并發隊列裡的任務後面的任務不必等待前面的任務執行完畢再執行,可以多個同時執行,同一時刻該并行隊列裡的任務可以有多個正在執行。
程式猿神奇的手,每時每刻,這雙手都在改變着世界的互動方式!
本文轉自當天真遇到現實部落格園部落格,原文連結:http://www.cnblogs.com/XYQ-208910/p/4860040.html,如需轉載請自行聯系原作者