Java语言BIO、NIO、AIO模型

简介: 本文介绍Java语言BIO、NIO、AIO模型

前言

我们知道,UNIX环境下常见的网络I/O模型有5种:

  • 同步阻塞
  • 同步非阻塞
  • I/O复用
  • 信号驱动
  • 异步非阻塞

那么基于上述五种模型,Java中,随着NIO和AIO(NIO 2.0)的引入,一般具有以下三种网络编程模型:

  • BIO
  • NIO
  • AIO

这次,我们就简单聊聊这三种网络编程模型。

BIO

BIO是一个经典的网络编程模型,是通常我们实现一个服务器端程序的过程。

步骤如下:

  • 主线程accept请求阻塞。
  • 请求到达,创建新的线程来处理这个socket,完成对客户端的响应。
  • 主线程继续accept下一个请求。

这个模型的一个明显的缺点:

当客户端连接快速增长时,服务器端创建的线程也会骤增,系统性能可能会骤降。

因此,在该模型的基础上,可以创建线程池,从而避免对每个客户端线程都创建一个新的服务器端线程,进而提升性能(创建线程是很耗费资源的,尽管线程可以看做轻量级进程)。

可参考Tomcat的BIO Connector。

这种方式也有被称为“伪异步I/O”,因为它是把请求抛到线程池中异步等待处理。

NIO

Java的NIO类库从JDK1.4(Java4)开始引入,这里NIO主要指非阻塞I/O,主要使用Selector多路复用器来实现的。

Selector在Linux等主流操作系统中是通过epoll实现的。

epoll 详解

epoll 百度百科

Java NIO Selector 剖析

NIO的实现流程类似于select:

  • 创建ServerSocketChannel监听客户端连接并绑定监听窗口,设置为非阻塞模式。
  • 创建Reactor线程,创建多路复用器Selector并启动线程。
  • 将ServerSocketChannel注册到Reactor线程的Selector上。监听accept事件。
  • Selector在线程run方法中无限循环轮询准备就绪的key。
  • Selector监听到新的客户端接入,处理新的请求,完成TCP三次握手,建立物理连接。
  • 将新的客户端连接注册到Selector上,监听读操作。读取客户端发送的网络消息。
  • 客户端发送的数据就绪则读取客户端请求,进行处理。

AIO

传说中的AIO其实是NIO 2.0,Java的AIO类库从JDK1.7(Java7)引入,它提供了异步文件通道和异步socket通道的实现。

AIO底层在Windows上是通过IOCP实现的,在Linux上则是通过epoll实现的。

IOCP 解读

IOCP 百度百科

LinuxAsynchronousChannelProvider.java

UnixAsynchronousServerSocketChannelImpl.java

流程:

  • 创建AsynchronousServerSocketChannel,绑定监听端口。
  • 调用AsynchronousServerSocketChannel的accpet方法,传入自己实现的CompletionHandler。包括上一步都是非阻塞的。
  • 连接传入,回调CompletionHandler的completed方法,在里面,调用AsynchronousSocketChannel的read方法,传入负责处理数据的CompletionHandler。
  • 数据就绪,触发负责处理数据的CompletionHandler的completed方法。继续做下一步处理即可。
  • 写入操作类似,也需要传入CompletionHandler。

AIO比起NIO,有了不少的简化。

对比

对比指标 同步阻塞IO 伪异步IO NIO AIO
客户端数目 : 服务器端 I/O 线程数目 1 : 1 m : n m : 1 m : 0
网络 I/O 模型 同步阻塞 I/O 同步阻塞I/O 同步非阻塞I/O 异步非阻塞I/O
吞吐量 较低 一般 较高 较高
编程复杂度 比较简单 比较简单 非常复杂 比较复杂

说明

本文首发于CSDN,为博主本人创作,修改后搬运至阿里云开发者社区发表。

相关文章
|
21天前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
57 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
11天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
11 1
|
18天前
|
Java 程序员 编译器
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。本文通过示例详细解析了保留字的定义、作用及与自定义标识符的区别,帮助开发者避免因误用保留字而导致的编译错误,确保代码的正确性和可读性。
38 3
|
20天前
|
移动开发 Java 大数据
深入探索Java语言的核心优势与现代应用实践
【10月更文挑战第10天】深入探索Java语言的核心优势与现代应用实践
34 4
|
25天前
|
分布式计算 安全 Java
Java语言的特点?
Java语言的特点?
|
4月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
6月前
|
存储 监控 Java
深入探索Java语言的NIO(New I/O)技术
深入探索Java语言的NIO(New I/O)技术
|
4月前
|
Java
Java中的NIO编程详解
Java中的NIO编程详解
|
4月前
|
Java 大数据
如何在Java中进行网络编程:Socket与NIO
如何在Java中进行网络编程:Socket与NIO
|
4月前
|
Java
Java中的NIO编程详解
Java中的NIO编程详解