GCD的隊列有兩種,一種是串行隊列,一種是并發隊列。
串行隊列:
任務按往隊列裡的添加先後順序執行,先進先出(FIFO),前一個任務執行完再開始執行下一個任務。(我們開發中主線程隊列就是一個串行隊列,是以我們經常在主線程寫的一般任務(不考慮多線程),都是順序執行的)。
注意一個串行隊列裡隻有一個線程。
并發隊列:
任務會在這個隊列中新開線程,并發同時執行(無序)。
我們GCD使用常伴有dispatch_sync和dispatch_async,這就是同步執行和異步執行。
同步和異步
同步執行:任務都在目前線程中執行,執行過程中會阻塞目前線程。
異步執行:任務會開辟新的線程,并在新的線程中執行,不會阻塞目前線程。
注意
1.同步執行沒有開啟新線程的能力, 所有的任務都隻能在目前線程執行
2.異步執行有開啟新線程的能力, 但是, 有開啟新線程的能力, 也不一定會利用這種能力, 也就是說, 異步執行是否開啟新線程, 需要具體問題具體分析
3.并發隊列中的任務會放到不同的線程中去執行.
4.串行隊列中的任務隻會放到同一線程中去執行.
基本介紹算是完了,隊列有2種,執行方式有2種,那麼他們互相組合會是什麼情況呢?
很顯然,它們可以組合成4種情況:
1).串行隊列同步執行:任務都在目前線程執行(同步),并且順序執行(串行)
2).串行隊列異步執行:任務都在開辟的新的子線程中執行(異步),并且順序執行(串行)
3).并發隊列同步執行:任務都在目前線程執行(同步),但是是順序執行的(并沒有展現并發的特性)
4).并發隊列異步執行:任務在開辟的多個子線程中執行(異步),并且是同時執行的(并發)
驗證:
1.串行隊列同步執行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
NSLog(@"task4---%@",[NSThread currentThread]);
結果
1 2 3 4 5 6 7 8 | |
分析:任務是在目前線程(目前是主線程)順序執行的。這也驗證了
串行隊列同步執行:任務都在目前線程執行(同步),并且順序執行(串行)
這裡需要注意的是代碼直接在viewDidLoad裡寫的,主隊列也是一個串行隊列,但在主線程中使用主隊列同步執行會造成死鎖,這裡不讨論這個。另外,若在viewDidLoad新開一個子線程,去執行代碼,結果是同樣可以驗證的:
1 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 | |
2.串行隊列異步執行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 | |
分析:主線程異步調用,我們先分析加到隊列裡的task任務1、2、3,确實都是在開辟了的新線程{number = 3, name = (null)}上順序執行的,關于task4,由于是異步的,它也沒加入隊列queue,啥時候輸出就看電腦心情了...驗證結果:
串行隊列異步執行:任務都在開辟的新的子線程中執行(異步),并且順序執行(串行)
這裡需要注意,由于新建立了串行線程,是以任務會在新開辟的線程上執行,若是直接在主隊列異步調用,任務執行都在主線程上。
3.并發隊列同步執行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 | |
分析:任務是在目前線程(是主線程沒有開辟新線程)順序執行的,跟串行同步一樣,雖是并發隊列,卻不能并發。得到驗證結果:
并發隊列同步執行:任務都在目前線程執行(同步),但是是順序執行的(并沒有展現并發的特性)
4.并發隊列異步執行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 | |
分析:先看task4吧,沒有加入隊列,是以肯定是在主線程執行的,由于異步,啥時候執行還是要看電腦心情...好了,言歸正傳,我們看加入到并發隊列裡的任務1、2、3,三個運作結果證明它們是在不同的線程中無序執行的,每個任務都開辟了新的線程去執行,并且執行順序是無序的,展現了并發的特性。是以我們經常也是使用這種方式做一些需求。驗證結果:
并發隊列異步執行:任務在開辟的多個子線程中執行(異步),并且是同時執行的(并發)
最後總結一下:了解了串行并發和同步異步,我們的開發會變得更加高效,邏輯也會更加清晰,若你暫時沒沒弄懂,可以再回上去看看理論,跟着理論敲敲代碼來加深了解