`

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中。

分享到:
评论

相关推荐

    javaIO模型1

    javaIO模型1

    Java IO 模型常见面试题总结 · .pdf

    Java IO 模型常见面试题总结 · .pdf

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

    主要介绍了Java三种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编程中的IO模型详解:BIO,NIO,AIO的区别与实际应用场景分析

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

    完整版 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模型 详解

    说说IO:IO原理与解析.zip

    IO模型;IO性能的重要指标;文件系统;逻辑卷管理;Driver & IO Channel;RAID;三分天下 适用人群:Java开发人员 使用场景:想学习JavaIO以及在IO开发中遇到瓶颈 目标:通过本教程的讨论与解析,更加深刻的理解和...

    io:java io学习项目

    线程了解Java内存模型了解Java的并发包,如锁,读写锁,Barrier,Executer和Future了解Java 8的Lambda表达式和Streaming API理解TCP/IP协议族理解HTTP协议和REST API理解多路复用和非阻塞IO熟悉Socket编程,...

    Scalable IO in Java原文和翻译

    Doug Lea大神的一篇PPT文档和翻译文档,里面介绍了多种Reactor模型的设计,注意是借助翻译软件进行的翻译。

Global site tag (gtag.js) - Google Analytics