转载请引用:一个故事讲清楚NIO

  假设某银行只有10个职员。该银行的业务流程分为以下4个步骤:

1) 顾客填申请表(5分钟);

2) 职员审核(1分钟);

3) 职员叫保安去金库取钱(3分钟);

4) 职员打印票据,并将钱和票据返回给顾客(1分钟)。

  我们看看银行不同的工作方式对其工作效率到底有何影响。

1 BIO方式

  每来一个顾客,马上由一位职员来接待处理,并且这个职员需要负责以上4个完整流程。当超过10个顾客时,剩余的顾客需要排队等候。

  我们算算这个银行一个小时到底能处理多少顾客?一个职员处理一个顾客需要10分钟(5+1+3+1)时间,一个小时(60分钟)能处理6个顾客,一共10个职员,那就是只能处理60个顾客。

  可以看到银行职员的工作状态并不饱和,比如在第1步,其实是处于等待中。

  这种工作其实就是BIO,每次来一个请求(顾客),就分配到线程池中由一个线程(职员)处理,如果超出了线程池的最大上限(10个),就扔到队列等待 。

2 NIO方式

  如何提高银行的吞吐量呢?

  思路:分而治之,将任务拆分开来,由专门的人负责专门的任务。

  具体来讲,银行专门指派一名职员A,A的工作就是每当有顾客到银行,他就递上表格让顾客填写,每当有顾客填好表后,A就将其随机指派给剩余的9名职员完成后续步骤。

  我们计算下这种工作方式下银行一个小时到底能处理多少顾客?

  假设顾客非常多,职员A的工作处于饱和中,他不断的将填好表的顾客带到柜台处理,柜台一个职员5分钟能处理完一个顾客,一个小时9名职员能处理:9*(60/5)=108。

  可见工作方式的转变能带来效率的极大提升。

这种工作方式其实就NIO的思路。下图是非常经典的NIO说明图,mainReactor线程负责监听server socket,accept新连接,并将建立的socket分派给subReactor;subReactor可以是一个线程,也可以是线程池(一般可以设置为CPU核数),负责多路分离已连接的socket,读写网络数据,这里的读写网络数据可类比顾客填表这一耗时动作,对具体的业务处理功能,其扔给worker线程池完成。

  可以看到典型NIO有三类线程,分别是mainReactor线程、subReactor线程、work线程。不同的线程干专业的事情,最终每个线程都没空着,系统的吞吐量自然就上去了。

3 异步方式

  第二种工作方式有没有什么可以提高的地方呢?

  仔细查看可发现第3步骤这3分钟柜台职员是在等待中度过的,那怎么能让柜台职员保持满负荷呢?

  还是分而治之的思路,指派1个职员B来专门负责第3步骤。每当柜台员工完成第2步时,就通知职员B来负责与保安沟通取钱。这时候柜台员工可以继续处理下一个顾客。当职员B拿到钱之后,他会怎么办呢?他会通知顾客钱已经到柜台了,让顾客重新排队处理,当柜台职员再次服务该顾客时,发现该顾客前3步已经完成,直接执行第4步即可。

  我们可以算算通过这种方法,银行的吞吐量能提高到多少。

  假设职员B的工作非常饱和,柜台一个职员现在2分钟能处理完一个顾客,一个小时8名职员能处理:8*(60/2)=240。

  在当今web服务中,经常需要通过RPC或者Http等方式调用第三方服务,这里对应的就是第3步,如果这步耗时较长,通过异步方式将能极大降低资源使用率。

  jetty Continuations 就实现了上述异步方式,有兴趣的同学可以去尝试下(http://wiki.eclipse.org/Jetty/Feature/Continuations)。

  NIO+异步的方式能让少量的线程(资源)做大量的事情,这适用于很多应用场景,比如代理服务、api服务、长连接服务等等,这些应用如果用同步方式将耗费大量机器资源。尽管NIO+异步能提高系统吞吐量,但其并不能让一个请求的等待时间下降,相反可能会增加等待时间。

4 小结

  总结就一句:“分而治之,将任务拆分开来,由专门的人负责专门的任务”,这不仅在计算机领域生效,在整个社会领域都生效。

转载于:https://www.cnblogs.com/lixuwu/p/10746439.html

一个故事讲清楚BIO NIO 异步相关推荐

  1. 牛逼!一个故事讲清楚 NIO 了

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:zhanlijun 原文链接:http://www. ...

  2. 一个故事讲清楚 NIO

    假设某银行只有10个职员.该银行的业务流程分为以下4个步骤: 1) 顾客填申请表(5分钟): 2) 职员审核(1分钟): 3) 职员叫保安去金库取钱(3分钟): 4) 职员打印票据,并将钱和票据返回给 ...

  3. 一个故事讲清楚NIO

    本文为转载文章,原文链接:http://www.cnblogs.com/LBSer/p/4622749.html 假设某银行只有10个职员.该银行的业务流程分为以下4个步骤: 1) 顾客填申请表(5分 ...

  4. [Python] 小明又迟到了……一个故事讲清楚 Python 循环嵌套

    Python 语言允许在一个循环体里面嵌入另一个循环.循环嵌套的语法形式如下: 1.Python for 循环嵌套: 语法: for iteration_var in sequence:for ite ...

  5. 关于BIO | NIO | AIO的讨论

    关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BIO | NIO | AIO,本身的描述都是在Java语言的基础上的.而描述IO,我们需要从两个 ...

  6. 也谈BIO | NIO | AIO (Java版--转)

    http://my.oschina.net/bluesky0leon/blog/132361 关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BI ...

  7. 什么是BIO | NIO | AIO

    在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步 ...

  8. 没那么复杂,只需要一个故事就能理解NIO!

    原文链接:http://www.cnblogs.com/LBSer 前言 假设某银行只有10个职员.该银行的业务流程分为以下4个步骤: 1) 顾客填申请表(5分钟): 2) 职员审核(1分钟): 3) ...

  9. 【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)...

    网上有很多讲同步/异步/阻塞/非阻塞/BIO/NIO/AIO的文章,但是都没有达到我的心里预期,于是自己写一篇出来. 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数 ...

最新文章

  1. Flutter 基础Widgets之AppBar详解
  2. UI组件之TextView及其子类
  3. Cloud for Customer work center的数据是如何从ABAP Netweaver返回给前端的
  4. SQL Server 2008之DMF
  5. hive 导入mysql数据库_求助 Hive 导入MYsql 数据库 报错啊
  6. UVA - 540:Team Queue
  7. 【转】状态机思路在程序设计中的应用
  8. python3 使用 pi3 安装软件时候,报错找不到 SSL 附解决方法
  9. [golang note] 工程组织
  10. docker -v 覆盖了容器中的文件_Docker容器之安装Mysql
  11. 开博第一篇:一个关于正则表达式相关的问题
  12. Python科学计算系列2—不等式和不等式组
  13. banner设圆角_Banner设计技巧!
  14. [zz] 高端HIFI发烧音频DAC解码芯片排名
  15. 科学研究设计七:单案例设计
  16. 数据降维:主成分分析法(PCA)
  17. 用状态机做人物(AI)的状态切换以及动画效果——人物动画以及切换
  18. 常见前端面试题及答案-转载
  19. 阿卜杜拉·法兹里和两个哥哥的故事(二)
  20. 无需电脑的多平台推流编码器

热门文章

  1. 岛屿类-网格类问题-DFS | 力扣695. 岛屿的最大面积
  2. Oracle 的关联子查询(correlated subquery) 简介.
  3. require.js的用法
  4. 计算机组成原理试卷五套,计算机组成原理(五套试题)
  5. linux红外驱动程序,基于Linux操作系统和红外发射器实现系统模块的设计
  6. 【分享】Oracle 常用运维命令大全
  7. linux命令的导入,[导入]Linux基本命令
  8. 内存管理vma_(十三)Linux内存管理之vma/malloc/mmap
  9. Serverless 如何在阿里巴巴实现规模化落地?
  10. 视频需求超平常数 10 倍,却节省了 60% 的 IT 成本投入是一种什么样的体验?