多線程開發用了好久,可是一直沒去深刻了解。長久以來一直有一些迷惑。直到深刻了解後,才發現了之前的理解有很多錯誤的地方。html
單線程等於同步,多線程等於異步node
Node.js表示不服,我就是單線程,我也能異步。談一談Node中的異步和單線程。
看完這篇文章我明白了單線程也能異步,把IO等耗時的操做比做燒水,我能夠在這個時候切菜,這就是異步啊。
等等,彷佛有點不對,那io又誰來開啓,又誰來通知cpu我已經結束了呢?
Node.js異步IO的實現,這篇文章解決了個人疑惑。ios
恍然大悟,我如今的理解就是,會有一個可運行的線程池在等待cpu的使用權。相似IO,網絡請求這種耗時乾等的操做,線程會放到須要等待的線程池中(阻塞),不會獲取cpu的使用權,直到操做完成git
這個理解了,併發和並行就很容易了。github
概念都講結束了,如今能夠談談iOS的多線程了。其實理論都同樣,無非線程的得到,開啓,結束等。可是iOS有個不一樣,他有GCD,那真是神器。
關於GCD的串行隊列,並行隊列,一直以來都有一個錯誤的理解:網絡
隊列就是線程,async就是另開線程,sync就是阻塞線程多線程
實踐才能出真知,要想真明白,async,sync,串行隊列,並行隊列,主隊列,仍是要親自測一下才行。併發
//主隊列 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"%@",[NSThread currentThread]); }); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"%@",[NSThread currentThread]); }); //串行隊列 dispatch_queue_t ser_queue = dispatch_queue_create("串行", DISPATCH_QUEUE_SERIAL); dispatch_async(ser_queue, ^{ NSLog(@"1-%@",[NSThread currentThread]); }); dispatch_async(ser_queue, ^{ NSLog(@"2-%@",[NSThread currentThread]); }); dispatch_sync(ser_queue, ^{ NSLog(@"3-%@",[NSThread currentThread]); }); //並行隊列 dispatch_queue_t con_queue = dispatch_queue_create("並行", DISPATCH_QUEUE_CONCURRENT); dispatch_async(con_queue, ^{ NSLog(@"1-%@",[NSThread currentThread]); }); dispatch_async(con_queue, ^{ NSLog(@"2-%@",[NSThread currentThread]); }); dispatch_sync(con_queue, ^{ NSLog(@"3-%@",[NSThread currentThread]); });
dispatch_queue_t ser_queue = dispatch_queue_create("串行", DISPATCH_QUEUE_SERIAL); dispatch_queue_t con_queue = dispatch_queue_create("並行", DISPATCH_QUEUE_CONCURRENT); dispatch_async(ser_queue, ^{ NSLog(@"1-%@",[NSThread currentThread]); dispatch_async(ser_queue, ^{ NSLog(@"1-%@",[NSThread currentThread]); }); }); dispatch_async(ser_queue, ^{ NSLog(@"2-%@",[NSThread currentThread]); dispatch_async(con_queue, ^{ NSLog(@"2-%@",[NSThread currentThread]); }); }); dispatch_async(con_queue, ^{ NSLog(@"3-%@",[NSThread currentThread]); dispatch_async(con_queue, ^{ NSLog(@"3-%@",[NSThread currentThread]); }); }); dispatch_async(con_queue, ^{ NSLog(@"4-%@",[NSThread currentThread]); dispatch_async(ser_queue, ^{ NSLog(@"4-%@",[NSThread currentThread]); }); }); dispatch_async(ser_queue, ^{ NSLog(@"5-%@",[NSThread currentThread]); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"5-%@",[NSThread currentThread]); }); }); dispatch_async(con_queue, ^{ NSLog(@"6-%@",[NSThread currentThread]); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"6-%@",[NSThread currentThread]); }); });
dispatch_async(ser_queue, ^{ NSLog(@"1-%@",[NSThread currentThread]); dispatch_sync(ser_queue, ^{ NSLog(@"1-%@",[NSThread currentThread]); }); }); dispatch_async(ser_queue, ^{ NSLog(@"2-%@",[NSThread currentThread]); dispatch_sync(con_queue, ^{ NSLog(@"2-%@",[NSThread currentThread]); }); }); dispatch_async(con_queue, ^{ NSLog(@"3-%@",[NSThread currentThread]); dispatch_sync(con_queue, ^{ NSLog(@"3-%@",[NSThread currentThread]); }); }); dispatch_async(con_queue, ^{ NSLog(@"4-%@",[NSThread currentThread]); dispatch_sync(ser_queue, ^{ NSLog(@"4-%@",[NSThread currentThread]); }); }); dispatch_async(ser_queue, ^{ NSLog(@"5-%@",[NSThread currentThread]); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"5-%@",[NSThread currentThread]); }); }); dispatch_async(con_queue, ^{ NSLog(@"6-%@",[NSThread currentThread]); dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"6-%@",[NSThread currentThread]); }); });
結論:
結果就不貼出來了,仍是本身親自測下比較好。看看本身的想法和答案是否一致但是一件很快樂的事情。
基本上覆蓋了全部可能。感受更像是面向隊列來的,線程的調度是系統本身分配的。異步
測下來感受就是回答了兩個問題:async
個人答案:
GCD是神器,還有好多須要學習的地方,推薦幾篇經典的文章:
GCD掃盲篇,巧談GCD
GCD進階篇
死鎖,圖文並茂,清晰易懂