面試iOS 90%人可能都會回答錯誤的一個多線程基礎題

這是某大廠的面試原題,我當時第一問回答對了,而後第二問就涼涼了。

題目描述:面試

一問:GCD是同步仍是異步狀況會開啓多線程swift

答:同步是不會開啓新的線程的,異步纔會開啓新的線程。多線程

這個沒啥難度,基本都是必會的。經過代碼驗證同步在串行隊列和併發隊列狀況下會不會建立新的線程併發

驗證代碼:異步

dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t conQueue = dispatch_queue_create("conQueue", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"(1).=====%@",[NSThread currentThread]);
    dispatch_sync(serialQueue, ^{
      NSLog(@"(2).=====%@",[NSThread currentThread]);
    });
    dispatch_sync(conQueue, ^{
      NSLog(@"(3).=====%@",[NSThread currentThread]);
    });
複製代碼

輸出結果:async

(1).=====<NSThread: 0x2837f6f00>{number = 1, name = main}
(2).=====<NSThread: 0x2837f6f00>{number = 1, name = main}
(3).=====<NSThread: 0x2837f6f00>{number = 1, name = main}
複製代碼

能夠看出同步是不會產生新的線程。固然問題確定不會這麼簡單就結束了。優化


二問:異步必定會開啓新的線程嗎。spa

答:不會,異步在主隊列裏不會建立新的線程,在其餘串行和併發隊列都會建立新的子線程線程

驗證代碼:code

dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t conQueue = dispatch_queue_create("conQueue", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"(1).=====%@",[NSThread currentThread]);
    dispatch_async(serialQueue, ^{
      NSLog(@"(2).=====%@",[NSThread currentThread]);
    });
    dispatch_async(conQueue, ^{
      NSLog(@"(3).=====%@",[NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
      NSLog(@"(4).=====%@",[NSThread currentThread]);
    });
複製代碼

輸出結果:

(1).=====<NSThread: 0x2800a6f00>{number = 1, name = main}
(2).=====<NSThread: 0x2800ca5c0>{number = 3, name = (null)}
(3).=====<NSThread: 0x2800ca5c0>{number = 3, name = (null)}
(4).=====<NSThread: 0x2800a6f00>{number = 1, name = main}
複製代碼

看結果(1)和(4)能夠肯定,在異步主隊列確實沒有開啓新的線程,兩個都是main線程,number號爲1.

再看(2)和(3),發現確實是建立了新的線程。可是仔細看線程號 發現(2)和(3) 對應的 number 都是3 。 也就是這兩個異步動做只建立了一個新的線程。按照常識來講不是應該建立兩個不一樣線程嗎?

這兒就要從時間和空間談到GCD對線程調度優化問題了。

GCD在執行多個異步操做的時候,會從時間和空間進行權衡會不會建立新的線程,通常每個任務開啓一個線程這樣時間最優,可是線程太多會消耗內存空間。因此GCD會自動權衡根據任務分配合適的線程數,從而達到空間和時間的最優。

固然具體GCD是怎麼作的,可能須要看源碼了...

這是我給這個問題的總結:

  • 同步:不具有開啓線程的能力,必定串行執行任務
  • 異步:具備開啓線程的能力,可是在主隊列裏不會開啓新的線程。 若是在串行隊列和併發隊列裏開啓n個子線程,gcd優化以後未必會真的有n個子線程。
相關文章
相關標籤/搜索