对bio、nio、aio的理解

阻塞/非阻塞 同步/异步

  同步与异步关注的是消息的通知机制

  同步指的是在发出一个消息调用的时候,如果没有获得结果,该消息调用就不会返回,会一直等待,也就是处于一种阻塞状态。一旦该消息调用返回,就能立刻得到返回值。

  也就是说,调用者需要主动等待被调用者返回的结果

  异步指的是,在消息调用发出后,这个调用就直接返回了,没有返回结果。也就是说,异步调用发出后,调用者不会立刻得到结果。被调用者通过状态、通知或者回调函数来通知调用者。

  阻塞与非阻塞关注的是程序在等待调用结果(消息、返回值)时的状态

  阻塞调用是指在调用结果返回之前,当前的线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用正好相反,调用线程在没有得到结果之前,该调用也不会阻塞当前线程。

IO模型

阻塞式IO模型

image

非阻塞式IO模型

image

IO多路复用模型

image

异步IO模型

image

java中的NIO

BIO同步阻塞

  客户端在读取数据的时候会产生阻塞,直到有数据返回或者超时;服务器端也会一直阻塞到有客户端连接才会返回,每个客户端连接过来,服务器端后会启动一个线程去处理客户端的请求。

  BIO的优点就是简单。缺点是当客户端过多的时候,会创建大量的线程去处理客户端的请求,线程资源都很宝贵,线程数量快速膨胀后,会导致系统的性能急剧下降,最终会导致系统宕掉。使用线程池可以限制线程的数量,但如果有大量的并发请求,超过最大数量的线程就只能等待,知道线程池中有空闲的线程可以被复用。

NIO同步非阻塞

NIO提供了Buffer、Selector、Channel进行数据处理。selector是一个选择器,可以选择某一个channel去做某些事。一个线程可以对应一个selector,而一个selector可以轮询多个channel,每一个channel对应一个socket。与BIO相比,只用一个线程就可以轮询多个socket。NIO虽然是非阻塞的,但是在调用select()时,如果数据没有准备好,还是会产生阻塞。BIO是在读取数据的时候会产生阻塞,而NIO会在select的时候会产生阻塞。

AIO异步非阻塞

AIO的使用回调函数来完成异步操作,数据读取完成后,在被通知。

一张它们的对比图片

image


参考文献