Netty入门到超神系列-BIO、NIO、AIO的认识

简介: I/O概述I/O其实是Input,Output的缩写,意思是输入和输出,比如:把磁盘中的一个文件读入Java内存中,站在Java内存的角度来看就是输入即input, 可以使用Java提供的输入流如:InputStream#read 来实现。如果是把一个段文本内容从Java内存中保存到磁盘上的某个文件,站在Java内存的角度来说就是输出,可以使用Java提供的输出流:OutputStream#write() 来实现。再比如把一个数据通过网络发送给其他服务器就是输出,或者从其他服务器接收一段数据就是输入。I/O也是有很多种的,比如Java支持三种:BIO,NIO,AIO

前言

本文章是《Netty入门到超神系列》第一章,主要介绍java的三大I/O模型:BIO,NIO,AIO,因为Netty采用了NIO模型,要透彻Netty就得懂NIO原理,NIO又是在BIO基础进行演变,所以我们得对这些I/O都要有一些了解。

I/O概述

I/O其实是Input,Output的缩写,意思是输入和输出,比如:把磁盘中的一个文件读入Java内存中,站在Java内存的角度来看就是输入即input, 可以使用Java提供的输入流如:InputStream#read 来实现。如果是把一个段文本内容从Java内存中保存到磁盘上的某个文件,站在Java内存的角度来说就是输出,可以使用Java提供的输出流:OutputStream#write() 来实现。再比如把一个数据通过网络发送给其他服务器就是输出,或者从其他服务器接收一段数据就是输入。

I/O也是有很多种的,比如Java支持三种:BIO,NIO,AIO

同步/异步/阻塞/非阻塞

为了方便理解几种IO的思想,这里先了解一下同步异步和阻塞非阻塞,这几个概念比较抽象,我举个例子来说明

  • 同步与异步
    假如在A线程 开了一个B线程,如果A线程必须等到B线程执行完成拿到结果之后才能继续执行后续代码,这就是同步。
    反之如果A线程无需等待B线程执行结束就可以继续执行后续代码,这就是异步,A线程通常使用事件或回调机制来得到B线程的返回结果。
  • 阻塞与非阻塞
    阻塞是指I/O操作需要彻底完成后才能返回用户空间 ,非阻塞是指I/O操作被调用后立即返回一个状态值,无需等I/O操作彻底完成
    比如某个线程中通过 read 读取数据,如果当read不到数据时,线程得一直等待,直到read到数据线程才能继续往后执行,那这就是阻塞。
    反之如果线程 read 不到数据也不需要等待,可以继续往后执行,那这就是非阻塞。

BIO理解

BIO被称为 Blocking I/O,是同步并阻塞型IO,服务器实现模式为一个连接一个线程,我们以client / server 为例, 当Client客户端向 Server发起一个请求,Server就会创建一个线程来处理这个请求,如果该线程没有读取到数据,就会一直阻塞在这,等待客户端发送数据,这会造成不必要的线程开销,当并发大的时候会创建大量的线程,比较占用系统资源。优化方案是使用线程池。BIO模型示意图:

BIO是Java传统的IO模型,InputStream,OutputStream等输入输出流都是基于BIO,问题也比较明显,即:一个请求一个线程比较占用资源,另外当read()不到数据时线程会阻塞,导致性能达不到最优,所以BIO适用于并发连接少的业务场景。优点是程序简单容易理解。

NIO理解

NIO是non-blocking I/O 或者 New IO ,是同步非阻塞的IO模型,实现模式是一个线程处理多个请求,客户端发送的请求都会交给多路复用器去处理,多路复用器采用轮询机制,轮询到连接有IO请求就创建线程进行处理。NIO采用非阻塞机制,当线程读取不到客户端发送的数据也不会阻塞,这样该线程就可以做其他的事情。

BIO 和 NIO 的区别

  • BIO以流的方式处理数据,NIO以块(buffer)的方式处理数据,块的IO效率高于流的IO效率
  • BIO是阻塞IO,NIO是非阻塞IO
  • BIO使用字符流,或者字节流进行操作,NIO基于channel通道和buffer缓冲区进行操作
  • BIO适用于并发低的业务场景,NIO适用于并发高的业务场景

AIO理解

在进行 I/O 编程中,常用到两种模式:Reactor和 Proactor,Java 的 NIO 就是 Reactor ,AIO采用 Proactor 模式。

AIO: NIO2.0,或称为AIO(Asynchronous I/O),是异步非阻塞IO是对NIO的增强,AIO 引入异步通道的概念,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用。

目前 AIO 还没有广泛应用,Netty 也是基于NIO, 而不是AIO,所以这里不做过多讲解。

三种IO对比

目录
相关文章
|
5月前
|
缓存 网络协议 算法
Netty的基础入门(上)
Netty的基础入门(上)
188 1
|
2月前
|
设计模式
Lettuce的特性和内部实现问题之Netty NIO的性能优于BIO的问题如何解决
Lettuce的特性和内部实现问题之Netty NIO的性能优于BIO的问题如何解决
|
9天前
|
Java
Netty BIO/NIO/AIO介绍
Netty BIO/NIO/AIO介绍
|
2月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
69 0
|
2月前
|
存储 网络协议 Java
【Netty 神奇之旅】Java NIO 基础全解析:从零开始玩转高效网络编程!
【8月更文挑战第24天】本文介绍了Java NIO,一种非阻塞I/O模型,极大提升了Java应用程序在网络通信中的性能。核心组件包括Buffer、Channel、Selector和SocketChannel。通过示例代码展示了如何使用Java NIO进行服务器与客户端通信。此外,还介绍了基于Java NIO的高性能网络框架Netty,以及如何用Netty构建TCP服务器和客户端。熟悉这些技术和概念对于开发高并发网络应用至关重要。
51 0
|
5月前
|
Java 应用服务中间件 API
从零手写实现 tomcat-06-servlet bio/thread/nio/netty 池化处理
该文介绍了逐步改进的网络服务器实现,从最初的 BIO 基础版到使用线程池的 BIO+Thread,再到 NIO 版本和 NIO+Thread,最后展示了一个使用 Netty 框架的简洁实现。文章旨在说明如何解决阻塞问题,并对比不同模型的优劣,最终推荐使用 Netty 以简化 NIO 编程。
【Netty】NIO 网络编程 聊天室案例(三)
【Netty】NIO 网络编程 聊天室案例(三)
151 0
【Netty】NIO 网络编程 聊天室案例(三)
【Netty】NIO 网络编程 聊天室案例(二)
【Netty】NIO 网络编程 聊天室案例(二)
153 0
【Netty】NIO 网络编程 聊天室案例(一)
【Netty】NIO 网络编程 聊天室案例(一)
153 0
|
存储 缓存 NoSQL
跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)
本文将要分享的是如何从零实现一套基于Netty框架的分布式高可用IM系统,它将支持长连接网关管理、单聊、群聊、聊天记录查询、离线消息存储、消息推送、心跳、分布式唯一ID、红包、消息同步等功能,并且还支持集群部署。
13445 1