dispatch_queue_t serialQueue = dispatch_queue_create("com.lai.www", DISPATCH_QUEUE_SERIAL); dispatch_async(serialQueue, ^{ // NSLog(@"1"); sleep(3); NSLog(@"1"); }); dispatch_sync(serialQueue, ^{ sleep(1); NSLog(@"2"); }); dispatch_async(serialQueue, ^{ NSLog(@"3"); }); dispatch_sync(serialQueue, ^{ sleep(5); NSLog(@"4"); }); dispatch_async(serialQueue, ^{ NSLog(@"5"); });
看看上面的代碼,你猜猜會輸出什么東東? 反正在今天之前我會認為它輸出坑定不是有序的,之前一直認為串行就是一個一個執行,好,第一個是異步,那就異步去吧,第二個同步,同步執行完,去執行第三個,然后..... 同步就執行完,然后執行下一個,異步就不知道什么時候執行完了。
哈哈哈哈,今天我不得不對自己的想法勘稱sb。太自以為是了。從中就可以看出我不能理解串行隊列的本質。
那么什么是串行隊列?什么是並行隊列?
-
Concurrent: tasks are dequeued in FIFO order, but run concurrently and can finish in any order.
-
Serial: tasks execute one at a time in FIFO order
並發: 任務以FIFO從序列中移除,然后並發運行,可以按照任何順序完成。它會自動開啟多個線程同時執行任務
串行: 任務以FIFO從序列中一個一個執行。一次只調度一個任務,隊列中的任務一個接着一個地執行(一個任務執行完畢后,再執行下一個任務)而且只會開啟一條線程
為了再次證實串行隊列中只有一個線程執行任務:
dispatch_queue_t queue = dispatch_queue_create("com.lai.www", DISPATCH_QUEUE_SERIAL); for (int i = 0; i< 10;i++){ // 10個異步 dispatch_async(queue, ^{ NSLog(@"%@--%d",[NSThread currentThread], i); }); }
我們可以發現thread的地址是一樣的,那就證實了serial queue只有一個線程執行任務。然后我們測試一下並發隊列
dispatch_queue_t queue = dispatch_queue_create("com.lai.www", DISPATCH_QUEUE_CONCURRENT); for (int i = 0; i< 10;i++){ // 10個異步 dispatch_async(queue, ^{ NSLog(@"%@--%d",[NSThread currentThread], i); }); }
由上圖可以看出並發隊列中是有多個線程執行任務的。
比較上面兩個程序,我們僅僅是創建了兩個不同類型的queue,但是結果迥然不同,並發會開啟多個線程,執行的順序我們無法控制,至於那個線程執行那個任務由隊列決定,哪個任務先完成由CPU和操作系統決定,並且並發隊列中的線程是可以重復利用(線程池),這也是可以理解的,但是下面:
dispatch_queue_t queue = dispatch_queue_create("com.lai.www", DISPATCH_QUEUE_CONCURRENT); for (int i = 0; i< 10;i++){ // 10個異步 dispatch_sync(queue, ^{ NSLog(@"%@--%d",[NSThread currentThread], i); }); }
發現並發只能在異步函數下有效,name=main ,還不會創建新線程。所有的任務依次在主線程上執行。