Java的IO模型分为BIO,NIO和AIO,本文重点介绍BIO,NIO。只从原理角度介绍,比较他们的异同和各自特点,分析linux提供的IO系统调用及Java NIO实现原理。并且介绍一下NIO具体实现netty框架。
1.Linux IO模型和系统调用
Linux系统结构如下所示:
Linux的内核定义了TCP/IP协议簇的实现,系统调用提供了API供应用系统调用。Java Linux版本虚拟机就是调用Linux系统调用实现的,在说明Java io模型之前有必要先了解一下Linux系统调用提供的IO模型、事件模型和并发模型(线程模型)。
在Linux系统中将文件和网络连接等资源都定义为文件描述符,简称fd,对于网络连接成为socket,socket只是一种网络编程接口,可以理解为是TCP协议/UDP协议的实现,使用socket接口可以编写出应用层程序,例如应用服务器和FTP服务器等。
1.1 IO模型
IO模型分为阻塞IO,非阻塞IO,IO复用和信号触发机制四种。
阻塞IO执行的系统调用,例如socket的接收请求,建立连接,数据读取,数据写入等操作都会被系统挂起,直到等待事件到来为止;
非阻塞IO执行的系统调用后立刻返回,不需要等待事件完成。非阻塞IO通常会与IO复用模型共同使用才会起编写出高效的程序;
IO复用是程序通过系统调用IO复用函数向内核注册一组事件,内核当有事件到来时,触发程序执行,通常IO复用程序会同时监听多路socket来提高效率。Linux常用的IO复用函数有select,pool,epool。
信号触发机制类似于IO复用,注册FD到目标宿主进程,宿主进程捕捉到FD的就绪时间,然后触发信号处理程序操作FD进行非阻塞操作。
阻塞IO,IO复用,信号触发机制是同步IO操作,表现在触发事件时就绪事件,需要程序自己执行用户空间和内核空间的数据。非阻塞IO是异步操作,表现在所触发事件都是IO完成时间,即不需要程序自己拷贝用户空间和内核空间数据,由系统自动完成。
1.2 事件处理机制
在IO复用模型中会产生大量的IO事件,本节介绍两种高效的事件处理模型。
同步IO模型通常使用Reactor模型,异步IO模型通常使用Proactor模型。
1.2.1 Reactor模型
主线程只负责监听FD上的是否有事件发生,当有事件发生时,交给工作线程执行。工作线程负责建立连接,读写数据等操作。
1.2.2 Proactor模型
主线程处理IO操作,工作线程处理业务逻辑。
1.2.3模拟Proactor模型
主线程负责监听IO事件和读操作,工作线程负责处理业务逻辑。
1.3并发模型
1.3.1半同步/半异步并发模型
同步用于处理客户逻辑,并发用于处理IO请求。它有很多种变体。
1.3.2领导者/追谁者模型
一个线程池中有只有一个线程(领导者)处理IO接受事件,当接收到事件时自己处理其业务逻辑,并且选举出一个新的领导者,到该线程处理完成时已经有领导者则其变为追谁者,如果还没有产生领导者则自己成为领导者线程,这种模型好处是不需要进行线程上下文切换,也不许访问共享数据结构,不会对资源加锁,执行效率较高。
2.java nio介绍和优势
nio基于IO多路复用,事件驱动机制提高了IO处理能力,尤其提高了在长连接,大并发情况的性能。
IO操作可以分为建立连接,监听,接受请求,读取,写回,关闭等步骤。BIO操作使用一个线程来处理一个连接的所有步骤,当没有请求到来,连接不可读、不可写的时候会阻塞线程(可以理解为一个线程在不断间隔一段时间询问一下是否可用),这样会导致CPU线程的频繁切换,并且绝大多数是无用的切换,不适应于存在大量闲置状态的长连接,如果是短连接效果比较好。
而NIO在这个方面做了改进,若干监听器监听所有的SOCKET,当有事件到来时候在触发线程执行读操作,业务逻辑操作,写操作。监听器(selector)同时监听多个channel,甚至一个监听器可以监听所有channel的事件,selector的select方法在没有事件时候阻塞,有事件时候返回,调用selector.selectedKeySet()获取事件(连接每个阶段定义为事件,分为接受请求,可读,可写,连接上),交与业务线程去执行。只有若干的selector处于阻塞状态,其他业务线程如果没有业务处理则处于休眠状态,不耗费CPU时间。相比BIO每个连接都有一个线程阻塞确实节省了线程资源和CPU上下文切换时间。这在连接数很大,大部分连接处于空闲的情况下,性能提升尤为明显。
nio使用预先分配的buffer进行预读数据和预写数据,提高了发送和接收效率。当写入数据时候,先将数据写到buffer,当channel可写时候,写入到channel;当数据可读的时候先将数据读入到buffer,然后触发业务处理线程去处理buffer数据。
3.netty
netty是基于java nio实现的高效网络处理框架。netty的boss线程池负责监听端口上socket连接和断开事件,当有连接到来时创建Channel对象交给Worker线程池处理,Worker线程池负责监听channel上的可读可写事件,当有事件到来时创建ChannelPipeline(Channel事件的处理单元,一个Channel对应一个ChannelPipeline)来处理,ChannelPipeline上定义了ChannelHandler(读写操作处理单元,可有多个)用来处理读写事件,在ChannelHandler上通常会使用业务线程池来处理耗时的请求。
ServerBootstrap负责初始化server,包括绑定端口、设置Channel工厂、Boss线程池、Worker线程池、设置ChannelPipeline创建工厂、ChannelPipeline注册若干ChannelHandler,ChannelPipeline注册业务处理线程池等操作。
Boss线程池中每个线程监听一个端口,当有Socket到来时,Boss线程调用ChannelFactory创建Channel处理该Socket,然后请求Worker线程池的worker线程处理该Channel,一个Worker线程有一个selector监听多路Channel的读写事件,即IO复用,worker线程池默认数量为机器核心数的2倍。Worker线程循环读取selector,当有事件到来时调用ChannelPipelineFactory创建channelPipeline(一个Channel对应一个ChannelPipe,ChannelPipe上绑定了多个ChannelHandler)执行,ChannelHandler分为ChannelUpstreamHandler和ChannelDownstreamHandler,分别处理读取和写入事件。ChannelHandler是在worker线程中串行执行的,如果业务逻辑处理比较耗时,则会增加worker线程时间,处理业务逻辑建议使用业务处理线程池来处理。写入操作比较特殊,业务逻辑线程接受到入内容,然后写入到buffer,当worker线程接收到可写事件后,将buffer中消息内容写到channel中。
相关推荐
"Java IO 模型常见面试题总结" Java IO 模型是 Java 编程语言中的一种输入/输出机制,用于实现计算机系统与外部设备之间的通信过程。在计算机结构中,IO 描述了计算机系统与外部设备之间的通信过程。从应用程序的...
Java IO模型1主要涉及到的是Java在处理网络数据交互时的不同方式。这里有五种主要的IO模型,它们分别是阻塞IO(BIO)、非阻塞IO、IO多路复用、信号量和异步IO(AIO)。理解这些模型的关键在于区分同步与异步以及阻塞...
在Java IO模型中,当一个线程发起一个IO操作请求时,该线程会一直阻塞等待直到IO操作完成。这意味着如果一个线程正在执行一个读取操作,那么在此期间该线程无法执行其他任何任务,必须等到读取操作完成才能继续下...
Java的IO模型采用了装饰者模式(Decorator Pattern),这使得开发者可以根据具体需求动态地组合不同的流类来构建所需的IO功能。例如,如果需要一个具有缓冲功能的文件输入流,可以通过组合`FileInputStream`和`...
为了解决传统Java IO模型在高并发流量处理上的不足,Java NIO被引入,利用非阻塞和事件驱动的特性来提高服务器的性能和并发处理能力。本文将分析Java NIO与Java IO在性能上的对比,并尝试找出性能差异的原因,以及...
"Java三种IO模型原理实例详解" Java中的IO模型可以分为三种:BIO(同步阻塞)、NIO(同步非阻塞)和AIO(异步非阻塞)。每种模型都有其特点和应用场景。 BIO(同步阻塞) BIO是最古老的IO模型,在JDK1.4之前都是...
Java IO应届生培训讲义是一份面向刚毕业的大学生进行Java IO相关知识的培训资料,它涵盖了Java IO的基础知识、不同的IO模型以及Java中的BIO、NIO和AIO高级IO类库。下面详细解释这些知识点: 1. 用户空间和内核空间 ...
首先,我们来看传统的Java IO模型。IO模型基于流,数据是从输入流到输出流的单向传输。例如,`FileInputStream`和`FileOutputStream`用于读写文件,它们都是一次性处理一个字节或多个字节。IO模型是阻塞式的,意味着...
然而,传统的IO模型在处理大量并发连接时表现出效率较低的问题,为了解决这个问题,Java引入了NIO(Non-blocking Input/Output)模型。 **Java IO核心概念** Java IO的核心类包括InputStream、OutputStream、Reader...
Java IO模型还包括了异步I/O(Asynchronous IO),例如Java 7引入的`AsynchronousFileChannel`,允许异步读写文件,这对于大型文件操作特别有用,因为它可以在等待I/O完成时执行其他任务。 总的来说,Java IO提供了...
Java IO模型基于流(Stream)的概念,流是一组有序的数据序列,可以是字节流或字符流。根据流向,流分为输入流(Input Stream)和输出流(Output Stream)。根据数据类型,流又分为字节流(Byte Stream)和字符流...
JavaIO流详解归纳 Java 的核心库 java.io 提供了全面的 IO 接口,包括文件读写、标准设备输出等。Java 中 IO 是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。在项目开发中,IO 是非常...
### IO模型介绍与Java常见IO模型详解 #### 一、引言 在计算机科学领域,输入输出(Input/Output,简称IO)模型是系统中处理数据传输的关键技术之一。随着互联网的发展,网络通信的需求日益增长,传统的IO模型已经...
7. **NIO(New IO)**:从Java 1.4开始引入,NIO提供了一种非阻塞的I/O模型,适合高并发和大容量数据传输场景。关键组件包括选择器(Selector)、通道(Channel)和缓冲区(Buffer)。 8. **文件系统操作**:Java还提供了...
JAVA IO同步、异步详解 IO 操作是计算机系统中最基本的操作之一,它可以分为同步(Synchronous)和异步(Asynchronous)两种模式。同步IO 是指应用程序在执行IO 操作时,需要等待IO 操作完成后才能继续执行其他操作...
IO流的概念基于流(Stream)模型,数据以字节或字符序列的形式流动。Java IO库提供了丰富的类和接口来支持不同类型的流,包括字节流、字符流、对象流、缓冲流、转换流以及过滤流等。 字节流(Byte Stream)是处理...
- **BIO(Blocking IO)**:这是Java早期提供的IO模型,特点是简单易用,但效率较低,适用于连接数量较少且对响应时间要求不高的场景。 - **NIO(Non-blocking IO)**:NIO提供了非阻塞的能力,通过选择器可以同时...
Java IO(Input/Output)是Java平台中处理输入与输出数据的核心部分,它提供了丰富的类库,使得开发者能够高效地进行文件、网络、内存以及其他I/O流的操作。本篇文章将全面解析Java IO工具类,帮助你理解并掌握其在...