我类比一下BIO\NIO\AIO,服务器就是餐馆,客户端就是来餐馆的顾客。

BIO: 进来一个顾客(连接),餐馆(服务器)就分配一个服务员(线程)来服务它,这时候顾客很墨迹想半天都不知道点啥(请求的IO还没有到),这个服务员(线程)就一直等呀等。

一个顾客进来就给它分配一个服务员;一个连接进来就给它分配一个线程
问题:顾客多了,餐馆没有那么多服务员,餐馆就瘫痪了。JVM的线程超过最大数量了,服务器爆了。

NIO: 既然顾客(连接)很墨迹(IO流数据没到),那就一个服务员(线程)在巡堂(多路复用),挨个轮询看哪个桌子的顾客想好了。如果一个顾客可以点餐了(IO流有数据了),就给它喊一个服务员过来(创建一个线程)。

所有的顾客进来都只有一个服务员巡堂;所有的连接进来都对应一个线程,一个请求对应一个线程
当顾客想好了可以点餐了,分配一个专属服务员;当一个线程的IO流到达,分配一个线程。

问题:给一个点餐请求分配了服务员,但是服务员发现点的菜还没有买回来,服务员只有等着菜买回来才能给厨师。服务器的线程看到请求过来了,但是处理请求所需要的资源还暂时得不到,线程只有继续等着。

AIO: 既然要等到菜(可用资源)有了,服务员(线程)才能去给厨师下单(处理请求),于是餐馆让顾客在APP上下单,下单成功都有菜(OS先接收IO流的数据成功),这时候APP(OS)通知服务员(线程)才来把菜单交给厨师(处理请求)。

有些因为菜没有而无效的点餐,就不会分配服务员来服务了,不会为了无效的点餐分配服务员;不会为了无效的请求分配线程,* 一个有效的请求一个线程 **

BIO

服务器上的监听发现有一个客户端的连接过来了,就创建一个服务器端的线程与服务器连接。此时可能客户端的请求还没有来,线程就一直阻塞,等客户端的输入流有数据。
这样每个连接都会对应一个服务器的连接,而IO流是很慢很慢的,非常费服务器的资源。
最直白的BIO\NIO\AIO的解释

NIO

为了解决BIO一个请求一个服务器端线程,而大量线程都在等着IO流的弊端。NIO让所有的客户端连接都对应一个服务器端的线程

最直白的BIO\NIO\AIO的解释
原图片地址

AIO

为了解决NIO启动服务器线程处理输入流的时候,后端资源还没有到位,线程仍然阻塞等待资源的问题,让客户端的输入流先让OS接收,OS接收后通知应用启动线程处理请求,实现了异步非阻塞。

BIO是同步阻塞方式:所谓阻塞就是等着线程啥都不干光等着IO流的数据到达,必须等到IO流到达写入到程序空间才能做其他事情。

NIO是同步非阻塞:线程不会一直等着IO流的到达而不能做别的事,而是不断的轮询是否有数据到达。IO流到达java就会有一个线程立马来处理,这是个同步的过程。

AIO是异步非阻塞方式:客户端的IO过来,被操作系统先接收了才通知用户程序,这样没有应用的线程阻塞等着IO流;然后用户的线程也不直接接收IO流的数据,而是由操作系统收下后通知它处理,因此它是异步的。

相关文章:

  • 2021-07-13
  • 2021-11-05
猜你喜欢
  • 2021-06-03
  • 2021-11-03
  • 2021-04-10
  • 2021-04-30
相关资源
相似解决方案