异步编程杂谈(续)

在简单看了netty的代码后就入坑了异步非阻塞这一块的内容,前面也陆陆续续写了好几篇,最近的一篇居然是9月份的异步编程杂谈,后面由于各种原因加上自己懒就没有下文了….哪怕写了前几篇也总有点似懂非懂的感觉,新年到了,要重开这个坑,彻底搞清楚。

异步的好处

玩异步最重要的是要搞清楚它的好处是什么,然后才是代码分格的不一样,callback问题的解决。类似 nodejs,假设如果业务上可并行的代码比较少(个人感觉大量的业务代码就是并行度不高的),全都是下一步操作要等上一步的结果,代码里有不少 async/await,那可以说异步编程也未必能降低响应时间的(当然,并发量特别大的时候比起同步方式还是能带来响应时间的优势)。那异步编程带来了什么好处?

吞吐量,单机200个线程,同步模式就只能处理200个请求,一个线程处理整个的业务,遇到io操作就阻塞等待,cpu没有得到充分利用;再看异步模式,一个请求过来,如果100msCPU,100msIO,那总得响应时间还是200ms,没有降低,但是100msIO操作的时候线程得以释放去做另一个请求的100msCpu操作,CPU被充分利用了,单位时间处理请求数也增加了,吞吐量也增加了。

对于同步处理程序,同一线程会用于该请求的整个生命周期;相反,对于异步处理程序,可以将不同的线程分配给同一请求(在不同的时间)。

异步下,IO操作线程释放去做别的任务,IO操作不占一个线程?答案如下:没有!

异步代码释放请求线程,但这只能以牺牲系统中另一个线程为代价吧?没有,一点关系也没有。

要解释这个问题又要回到linux的io模型上,我们说io多路复用技术里多个连接会注册到一个select或者epoll,最终只阻塞到一个线程上。vertx在网络IO中使用的是NIO,那本地文件呢?同样的FileSystem里Vertx使用JDK7带来的AsynchronousFileChannel是绝对的异步模式。

https://msdn.microsoft.com/zh-cn/magazine/dn802603.aspx
https://www.ibm.com/developerworks/cn/linux/l-async/