多线程开发用了好久,可是一直没去深刻了解。长久以来一直有一些迷惑。直到深刻了解后,才发现了之前的理解有很多错误的地方。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进阶篇
死锁,图文并茂,清晰易懂