异步IO比同步阻塞IO性能更好吗?为何?

最近在看node.js, 介绍中提到node是异步io的方式实现, 性能比同步阻塞io的更好. 对于一个request而言, 若是咱们依赖io的结果, 异步io和同步阻塞io都是要等到io完成才能继续执行. 而同步阻塞io, 一旦阻塞就不会在得到cpu时间片, 那么为何异步的性能更好呢?node

这个问题以前在作Servlet AIO优化的时候就没想太明白. 如今回想起来tomcat这类server的BIO并发数是有瓶颈的, 即使是空跑也只能到1000个并发量级, 而Nginx能够作到C10k. 问题其实就出在线程的数量上面.tomcat

同步io模型须要对每一个请求建立一个线程, 在io时, 线程被block住, 虽然不消耗cpu, 但线程自己是有内存开销的. 虽然建立少许线程的开销在现代操做系统中很低, 可是这个量到达10k的并发以后, 这个量就很大了. 其次, 活跃线程的context switch开销也会消耗额外的cpu资源.多线程

而异步模型只建立固定的线程, (通常等于cpu核数), 处理并发的请求, 在io的地方用操做系统提供的异步io实现, 避免了线程频繁建立, 销毁和context switch的开销. 所以更快. 这里的快是指吞吐量更大, cpu资源的更有效利用.并发

有一点也须要注意, 就是从request进来到完成, 应用内各个节点和调用流程都要支持异步io调用, 不然一个节点不支持, 就退化成多线程的解决方式. 好比Servlet -> JDK -> 操做系统, 每一个环节都要作异步的支持.异步

最后说下同步, 异步, 阻塞, 非阻塞几点的区别.性能

同步异步是在调用的角度上面看, 同步是调用方主动完成操做. 而异步是在调用完成后, 被调用方执行回调完成操做.优化

阻塞非阻塞是指执行线程有没有中止执行, 阻塞是线程block住再也不得到cpu时间片, 非阻塞是指线程仍是active的, 能够继续得到时间片, 执行其余任务.操作系统