iOS 之GCD串行和併發隊列的理解

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。太自覺得是了。從中就能夠看出我不能理解串行隊列的本質。異步

那麼什麼是串行隊列?什麼是並行隊列?async

  • 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從序列中移除,而後併發運行,能夠按照任何順序完成。它會自動開啓多個線程同時執行任務spa

串行:  任務以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只有一個線程執行任務。而後咱們測試一下併發隊列code

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);
        });
    }

 

由上圖能夠看出併發隊列中是有多個線程執行任務的。blog

 

比較上面兩個程序,咱們僅僅是建立了兩個不一樣類型的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 ,還不會建立新線程。全部的任務依次在主線程上執行。

相關文章
相關標籤/搜索