没那么复杂,您只需要一个故事来了解NIO

原始链接:http://www.cnblogs.com/LBSer前言假设一家银行只有10名员工。

银行的业务流程分为以下四个步骤:1)客户填写申请表(5分钟); 2)工作人员审核(1分钟); 3)工作人员要求保安去金库取钱(3分钟); 4)工作人员打印账单,并将钱和账单退还给客户(1分钟)。

让我们看一下不同银行的工作方式如何影响其工作效率。

1 BIO方法每次客户来访时,工作人员都会立即收到并处理该工作,该工作人员负责上述4个完整的过程。

当客户超过10个时,其余客户需要排队等候。

让我们计算一下该银行在一小时内可以处理多少个客户?业务员处理一个客户需要10分钟(5 + 1 + 3 + 1),一个小时(60分钟)可以处理6个客户,总共10名员工,也就是说,只能处理60个客户。

可以看出,银行工作人员的工作状态还没有达到饱和。

例如,在第一步中,他们实际上正在等待。

这种工作实际上是BIO。

每次请求(客户)到来时,它都会分配给线程池并由线程(员工)进行处理。

如果超出了线程池(10)的最大限制,则将其扔入队列以等待。

2 NIO方法如何提高银行的吞吐量?想法:分而治之,分解任务,让特殊的人来负责特殊的任务。

具体来说,银行专门分配了一名职员A。

当客户到达银行时,A的工作是交出一张表格供客户填写。

每当客户填写表格时,A便将其随机分配给其余九个人。

员工完成了下一步。

让我们计算一下这种工作方式,银行在一小时内可以处理多少个客户?假设有很多客户,并且业务员A的工作已经饱和。

他不断地将填写表格的客户带到柜台进行处理。

柜台的一名职员可以在5分钟内处理一位客户,而9名员工可以在一个小时内处理一位客户:9 *(60/5)= 108。

可以看出,改变工作方法可以大大提高效率。

这种工作方式实际上是基于NIO的想法。

下图是一个非常经典的NIO插图。

mainReactor线程负责监视服务器套接字,接受新连接以及将已建立的套接字分配给subReactor。

subReactor可以是线程或线程池(通常可以将其设置为CPU内核数),负责对连接的套接字进行多路分解,读取和写入网络数据。

可以将此处的网络数据读写与客户填写表格的耗时操作进行比较。

对于特定的业务处理功能,它被扔到工作线程池中以完成任务。

可以看出,典型的NIO具有三种类型的线程,即mainReactor线程,subReactor线程和工作线程。

不同的线程会做一些专业的事情,最终每个线程都不可用,系统的吞吐量自然会上升。

3异步模式第二种工作模式是否有改进?仔细检查发现,柜台业务员在步骤3中等待了3分钟。

我们如何保持柜台业务员满负荷工作?或分而治之的思想,指派一名工作人员B负责第三步。

每当柜台工作人员完成步骤2时,都会通知工作人员B与保安人员进行通信以提取资金。

此时,柜台人员可以继续与下一位客户打交道。

员工B拿到钱后会怎么做?他将通知客户钱已经到达柜台,并要求客户再次排队。

当柜台业务员再次为客户提供服务时,他发现客户已经完成了前3个步骤,可以直接进行第4步。

我们可以计算出通过这种方法可以增加多少银行的吞吐量。

假设B员工的工作非常饱和,那么柜台上的一名员工现在可以在2分钟内处理一位客户,而8名员工在一小时内可以处理该客户:8 *(60/2)= 240。

在当今的Web服务中,通常必须通过RPC或Http调用第三方服务。

这对应于第三步。

如果此步骤花费很长时间,则异步方法将大大降低资源利用率。

Jetty Continuations实现了上述异步方法,感兴趣的学生可以尝试一下(http://wiki.eclipse.org/Jetty/Feature/Continuations)。

NIO +异步方法允许少量线程(资源)做很多事情。

这适用于许多应用程序场景,例如代理服务,api服务和持久连接服务。

这些应用程序将消耗大量机器

产品知识/行业、品牌资讯