????????什么是GCD?GCD--Grand Central Dispatch,是異步執行任務的技術之一。GCD提供非常簡潔的API,實現了極為復雜繁瑣的多線程編程。 開發者只需要定義想執行的任務并追加到適當的Dispatch Queue中,GCD就能生成必要的線程并高效執行任務。這對于我以前用C寫過多線程編程的人來說,GCD真是一項劃時代的技術。
1.概念理解
dispatch_sync--同步執行,同步操作會等待操作執行完成后再繼續執行接下來的代碼。不具備開啟線程的能力。
dispatch_async--異步執行,異步操作會在調用后立即返回,不會等待操作的執行結果。具備開啟線程的能力,雖然有這個能力,但是不能保證一定開啟了線程。
dispatch_sync和dispatch_async的主要區別在于是否等待操作執行完成。注意理解,這里的等待并不是當前線程停止,只是線程去執行新添加的同步任務去了(看到很多文章都說是當前線程停止)。
serial_queue--串行隊列,一次只能執行一個任務,必須等一個任務執行完成后才能執行下一個任務。
concurrent_queue--并行隊列,允許多個任務同時執行。
serial_queue和concurrent_queue的主要區別在于允許同時執行的任務數量。
2.dispatch_async 和?dispatch_sync 方法
1>dispatch_async +?concurrent_queue
? ? 會不會創建線程:會,一般同時開多條線程。
? ? 任務執行方式:并發執行
測試代碼如下
運行結果如下
2>dispatch_async +?serial_queue
????會不會創建線程:會,一般只開一條線程。
? ? 任務執行方式:串行執行
測試代碼如下
運行結果如下
3>dispatch_async + main_queue
????會不會創建線程:雖然有開啟線程的能力,但是碰到main_queue,也不會開啟線程,放進main_queue的任務一定是在主線程執行
? ? 任務執行方式:串行執行
測試代碼如下
運行結果如下
4>dispatch_sync +?concurrent_queue
????會不會創建線程:不會
? ? 任務執行方式:串行執行,這種情況并發隊列失去了并發的功能
測試代碼如下
運行結果如下
5>dispatch_sync + serial_queue
????會不會創建線程:不會
? ? 任務執行方式:串行執行
測試代碼如下
運行結果如下
6>dispatch_sync + main_queue
很遺憾告訴你,在主線程中,這種情況程序會崩潰。切記不要用到這種情況。那這種情況為什么會崩潰呢,該怎么理解呢?
崩潰代碼如下
主隊列正在執行A任務,這個時候以同步的方式向主隊列里面添加一個B任務,此時主隊列里面有兩個任務,A和B。因為主隊列是串行隊列,所以只能先執行完A任務才能執行后面的B任務。但是主隊列在執行A任務的時候碰到dispatch_sync方法,該方法只有在B任務執行完成后才會返回,所以此時dispatch_sync導致A任務無法執行下去。這樣A任務、B任務都沒辦法執行了,程序會崩潰。
再來考慮下面這種情況,這種情況是不會崩潰的,但是它為啥又不會崩潰呢?
這種情況和上面的區別就在于任務B不是同步加到主隊列的,而是加到另外一個serial_queue里面去的,因為此時存在兩個隊列,main_queue 和?serial_queue,任務A在?main_queue,任務B在?serial_queue,既然兩個任務是在兩個隊列中,那個B任務執行就不需要等待A任務執行完了。程序執行路徑是 任務A1--->任務B--->任務A2。這種情況也認證了dispatch_sync的同步等待不是當前線程停止,只是線程去執行新添加的同步任務去了。
7>dispatch_sync 更深層次的思考
同步任務沒有執行完畢,后面所有的任務都不會去執行,不管隊列是串行隊列還是并發隊列,所以它有相當于一個鎖的功能。這樣利用同步任務,能夠做到任務依賴關系,前一個任務是同步任務,它不執行完,隊列就不會調度后面的任務。