`

Java IO 模型

 
阅读更多

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 模型常见面试题总结 · .pdf

    "Java IO 模型常见面试题总结" Java IO 模型是 Java 编程语言中的一种输入/输出机制,用于实现计算机系统与外部设备之间的通信过程。在计算机结构中,IO 描述了计算机系统与外部设备之间的通信过程。从应用程序的...

    javaIO模型1

    javaIO模型1

    Java三种IO模型原理实例详解

    主要介绍了Java三种IO模型原理实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    JavaIO流详解归纳.pdf

    JavaIO流详解归纳 Java 的核心库 java.io 提供了全面的 IO 接口,包括文件读写、标准设备输出等。Java 中 IO 是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。在项目开发中,IO 是非常...

    Java IO应届生培训讲义

    个人给应届生培训用的讲义,主要是以Java IO为主题,包括IO的基本概念、IO模型、Java BIO ,NIO, NIO2。分享下

    JavaNIO浅析IO模型Java开发Java经验技巧共1

    JavaNIO浅析IO模型Java开发Java经验技巧共10页.pdf.zip

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    马士兵 java IO流 笔记 和分析

    以前学java时候看的马士兵老师的教程,老师讲的较快,有些不适应,自己做些笔记巩固练习,效果还不错,贴出来分析大家把,配图+示例。。。

    高性能IO模型浅析

    服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型。 (2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置...

    java-面试指北PDF版

    · Java IO 模型常见面试题总结 · 2022腾讯云Java工程师一面 + 被捞一面 + 二面面经 · MySQL 日志:常见的日志都有什么用? · MySQL 索引:索引为什么使用 B+树? · 如何设计一个排行榜? ·

    JAVA基础技术框架详解一.pdf

    1. JAVA IO模型:Reactor 模型和 Proactor 模型的对比,IO 模型的选择对系统性能的影响。 2. JAVA NIO:Introduction to NIO,NIO 的优缺,NIO 的使用场景,NIO 的实现机制。 3. JAVA Netty:Netty 的架构,Netty ...

    Java编程中的IO模型详解:BIO,NIO,AIO的区别与实际应用场景分析

    IO模型决定了数据的传输方式,Java支持BIO,NIO,AIO三种IO模型。BIO是同步阻塞模型,特点是一对一的客户端与处理线程关系,适用场景是连接数量较小并且固定的,优点是编程简单,但对服务器资源要求高。NIO是同步非...

    java IO、NIO、AIO详解.docx

    Java IO、NIO、AIO 是 Java 语言中三种不同的输入/输出机制,分别对应着不同的编程模型和设计理念。在高并发环境中,选择合适的输入/输出机制非常重要,本文将对 Java IO、NIO、AIO 进行详细的介绍和比较。 一、...

    完整版 Java基础入门教程 Java程序语言设计 04 IO流 输入输出流(共31页).ppt

    完整版 Java基础入门教程 Java程序语言设计 04 IO流 输入输出流(共31页).ppt 完整版 Java基础入门教程 Java程序语言设计 05 GUI AWT 事件模型(共27页).ppt 完整版 Java基础入门教程 Java程序语言设计 05 GUI GUI...

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO.pdf

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non...

    scalable io in java

    Scalable in in java .Doug Lee的著作,学习线程模型必备。

    Scalable IO in Java.zip

    Scalable IO in Java是java.util.concurrent包的作者,大师Doug Lea关于分析与构建可伸缩的高性能IO服务的一篇经典文章,在文章中Doug Lea通过各个角度,循序渐进的梳理了服务开发中的相关问题,以及在解决问题的...

    Socket高性能IO模型浅析

    (1)同步阻塞IO(BlockingIO):即传统的IO模型。(2)同步非阻塞IO(Non-blockingIO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(NewIO)库。(3)IO多...

    线程池深入 + IO模型 详解

    线程池深入 + IO模型 详解

Global site tag (gtag.js) - Google Analytics