Java相关

网络相关 - BIO/NIO/AIO

2020-04-06  本文已影响0人  万福来

基于BIO实现的伪异步I/O模型

采用单线程循环处理accept事件,当有客户端接入时,将客户端的socket封装成一个实现Runnable的Task放到后端的线程池中进行,线程池中维护一个消息队列N个活跃线程对队列中的任务进行异步处理。队列大小和线程数量可以固定大小,资源占用也就可控的,不用为每个客户端创建一个线程。

基于I/O多路复用实现NIO

NIO 是利用了单线程轮询事件的机制,通过高效地遍历就绪的 Channel,来决定做什么,仅仅 select 阶段是阻塞的,可以有效避免大量客户端连接时,频繁线程切换带来的问题,应用的扩展能力有了非常大的提高。

  1. 首先,通过 Selector.open() 创建一个 Selector,作为类似调度员的角色;
  2. 然后,创建一个 ServerSocketChannel,并且向 Selector 注册,通过指定 SelectionKey.OP_ACCEPT,告诉调度员,它关注的是新的连接请求;
  3. 为什么我们要明确配置非阻塞模式呢?这是因为阻塞模式下,注册操作是不允许的,会抛出 IllegalBlockingModeException 异常;
  4. Selector 阻塞在 select 操作,当有 Channel 发生接入请求,就会被唤醒;
  5. 然后根据selectionKey与客户端建立链接,链接成功后,获取ServerSocketChannel通道,
    并将该通道向Selector注册,开始关注通道可读状态;
  6. 当有客户端写入数据,通道状态为可读状态时,selector线程会通知开始处理读取客户端数据;
  7. 主要通过缓冲区ByteBuffer来读取数据,读是非阻塞的。
  8. 读完客户端数据,开始写处理,写也是非阻塞的。

缓冲区 Buffer

在NIO类库中,所有数据都是通过缓冲区处理的,在读取数据时,直接读到缓冲区中,写入数据时,写到缓冲区中。任何时候访问NIO中的数据都是通过缓冲区进行操作。
缓冲区本质是数组,常用的实现类有


image.png

通道 Channel

Channel 与InputStream/OutputStream区别
Channel 是一个通道,可以用于读、写或者同时读写,是全双工的,可以双向流通,不阻塞;
Channel 主要有两类,分别用于网络读写的和文件读写操作;
InputSteam 是输入流,只能用于读数据,而且没有数据时会一直阻塞;
OutputStream 是输出流,只能用于写入输出数据;

多路复用器 Selector

Selector可以通过一个线程轮询注册在其上的Channel,如果某个channel上有了新的TCP连接接入、读和写事件,这个channel就处于就绪状态,会被selector轮询出来,然后通过selectionKey可以获取就绪channel的集合,进行后续的I/O操作。
一个Selector可以同时轮询多个Channel,在jdk5update10版本中进行了优化,使用epoll代替了原来的select/poll实现,没有了最大连接接句柄的限制。

NIO2.0 又叫AIO

NIO2.0引入了新的异步通道的概念,提供了异步文件通道和异步套接字通道的实现,异步通道提供两种方式获取操作结果。

上一篇下一篇

猜你喜欢

热点阅读