首页 > 其他分享 >I/O模型:BIO、NIO、AIO

I/O模型:BIO、NIO、AIO

时间:2023-05-08 11:33:51浏览次数:40  
标签:BIO NIO 阻塞 AIO 线程 缓冲区 通道

Java共支持3种网络编程的I/O模型:BIO、NIO、AIO

BIO:

同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销


NIO:

同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求就进行处理


AIO:

异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由操作系统先完成了再通知服务器应用去启动线程进行处理,一般适用于连接数较多且连接时间较长的应用

二、BIO深入剖析
1、BIO概述
BIO(Blocking I/O)就是传统的Java IO编程,其相关的类和接口在java.io包下。BIO是同步阻塞的,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器)


2、BIO编程流程的梳理:

服务器端启动一个ServerSocket,注册端口,调用accpet方法监听客户端的Socket连接
客户端启动Socket对服务器进行通信,默认情况下服务器端需要对每个客户建立一个线程与之通讯

3、伪异步I/O
1)、概述
伪异步I/O采用线程池和任务队列实现,当客户端接入时,将客户端的Socket封装成一个Task(该任务实现java.lang.Runnable线程任务接口)交给后端的线程池中进行处理。JDK的线程池维护一个消息队列和N个活跃的线程,对消息队列中Socket任务进行处理,由于线程池可以设置消息队列的大小和最大线程数,因此,它的资源占用是可控的,无论多少个客户端并发访问,都不会导致资源的耗尽和宕机

2)总结

伪异步I/O采用了线程池实现,因此避免了为每个请求创建一个独立线程造成线程资源耗尽的问题,但由于底层依然是采用的同步阻塞模型,因此无法从根本上解决问题
如果单个消息处理的缓慢,或者服务器线程池中的全部线程都被阻塞,那么后续Socket的I/O消息都将在队列中排队。新的Socket请求将被拒绝,客户端会发生大量连接超时

三、NIO深入剖析
1、NIO概述
NIO(Non-Blocking IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。NIO可以理解为非阻塞IO,传统的IO的read和write只能阻塞执行,线程在读写IO期间不能干其他事情,比如调用socket.read()时,如果服务器一直没有数据传输过来,线程就一直阻塞,而NIO中可以配置socket为非阻塞模式
NIO相关类都被放在java.nio包及子包下,并且对原java.io包中的很多类进行改写
NIO有三大核心部分:Channel(通道)、Buffer(缓冲区)、Selector(选择器)
Java NIO的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情
通俗理解:NIO是可以做到用一个线程来处理多个操作的。假设有1000个请求过来,根据实际情况,可以分配20或者80个线程来处理。不像之前的阻塞IO那样,非得分配1000个
2、NIO和BIO的比较
BIO以流的方式处理数据,而NIO以块的方式处理数据,块I/O的效率比流I/O高很多
BIO是阻塞的,NIO则是非阻塞的
BIO基于字节流和字符流进行操作,而NIO基于Channel(通道)和Buffer(缓冲区)进行操作,数据总是从通道
读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择器)用于监听多个通道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道
3、NIO三大核心
NIO有三大核心部分:Channel(通道)、Buffer(缓冲区)、Selector(选择器)

Buffer缓冲区:

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。相比较直接对数组的操作,Buffer API更加容易操作和管理

Channel(通道):

Java NIO的通道类似流,但又有些不同:既可以从通道中读取数据,又可以写数据到通道。但流的(input或output)读写通常是单向的。通道可以非阻塞读取和写入通道,通道可以支持读取或写入缓冲区,也支持异步地读写

Selector选择器:

Selector是一个Java NIO组件,可以能够检查一个或多个NIO通道,并确定哪些通道已经准备好进行读取或写入。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接,提高效率

每个channel都会对应一个Buffer
一个线程对应Selector,一个Selector对应多个channel(连接)
程序切换到哪个channel是由事件决定的
Selector会根据不同的事件,在各个通道上切换
Buffer就是一个内存块,底层是一个数组
数据的读取写入是通过Buffer完成的,BIO中要么是输入流,或者是输出流,不能双向,但是NIO的Buffer是可以读也可以写
Java NIO系统的核心在于:通道(Channel)和缓冲区(Buffer)。通道表示打开到IO设备(例如:文件、套接字)的连接。若需要使用NIO系统,需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理。简而言之,Channel负责传输,Buffer负责存取数据

四、AIO简介
Java AIO(NIO 2.0)异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由操作系统先完成了再通知服务器应用去启动线程进行处理

与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可,这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序

标签:BIO,NIO,阻塞,AIO,线程,缓冲区,通道
From: https://www.cnblogs.com/october-sy/p/17381231.html

相关文章

  • SQL语法之:连表查询:union all
    1、准备两条sql查询出来的字段数必须一致表1字段:数据:表2字段:数据:2、使用1、两张表结构完全一样,查询字段顺序也一样selectID,NAME,SEX,AGE,NAME2fromT_01UNIONALLselectID,NAME,SEX,AGE,NAME2fromT_02;结果:2、查询字段顺序不一样,但是对应的......
  • javaAIO是什么
    网络IO进行时,需要将用户态切换为内核态,操作系统内核在进行网络IO时有等待数据、拷贝数据两个阶段。无论是阻塞IO、非阻塞IO、多路复用,都是同步IO,因为他们都是等数据准备好了,再使用当前线程去获取数据。IO类型等待数据阶段拷贝数据阶段用户态和内核态切换次数阻塞IOr......
  • SQL注入UNION攻击
    1.SQL注入UNION攻击当应用程序容易受到SQL注入的攻击并且查询结果在应用程序的响应中返回时,该UNION关键字可用于从数据库中的其他表中检索数据。这会导致SQL注入UNION攻击。关键字UNION SELECT允许您执行一个或多个其他查询,并将结果追加到原始查询。例如:SELECTa,bFR......
  • 解决OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll alread
    错误如下所示:OMP:Error#15:Initializinglibiomp5md.dll,butfoundlibiomp5md.dllalreadyinitialized.OMP:HintThismeansthatmultiplecopiesoftheOpenMPruntimehavebeenlinkedintotheprogram.Thatisdangerous,sinceitcandegradeperformanceorcau......
  • javaNIO多线程worker实现
    boss线程负责接收连接,worker线程负责处理IO事件。packagenet.yury.nio;importjava.io.IOException;importjava.net.InetSocketAddress;importjava.nio.ByteBuffer;importjava.nio.channels.*;importjava.nio.charset.StandardCharsets;importjava.util.ArrayList;......
  • javaNIO创建tcp服务器时的重要点
    在使用NIO创建非阻塞tcp服务器时,几个容易出现问题的点,如下代码注释所示:packagenet.yury.nio;importjava.io.IOException;importjava.net.InetSocketAddress;importjava.nio.ByteBuffer;importjava.nio.CharBuffer;importjava.nio.channels.*;importjava.nio.charse......
  • mv: cannot move '/usr/local/lib/R/site-library/00LOCK-Biobase/00new/Biobase' to
     01、安装Biobase 包的时候遇到如下问题mv:cannotmove'/usr/local/lib/R/site-library/00LOCK-Biobase/00new/Biobase'to'/usr/local/lib/R/site-library/Biobase':Permissiondenied 02、解决方法在R终端执行如下命令:Sys.setenv(R_INSTALL_STAGED=FALSE)......
  • Typora+MinIO+Python代码打造舒适协作环境
    作者:IT王小二博客:https://itwxe.com不知不觉大半年没更新了...前面小二介绍过使用Typora+MinIO+Java代码打造舒适写作环境,然后有很多大佬啊,说用Java来实现简直是杀鸡用上牛刀,小二想了想,确实有点...正好小二最近在学习Python,所以咱们就改用Python实现一版。安装MinIO安装参考......
  • windows下minio的使用
    主要是用于脱离公司服务器,在外需要开发时,本机启动开发测试使用使用方法,参照官网即可:https://min.io/download#/windows一点说明:命令行运行命令中C:\minio.exeserverF:\Data--console-address":9001"C:\minio.exe是下载的minio程序位置 F:\Data是存储数据位置......
  • 电脑无法进入bios
    说明我的双屏电脑重启不会显示品牌图标,按delete键也不能进入bios解决好像是因为nvida20系显卡驱动的问题,只能用HDMI线连接的显示屏才能正常进入bios,于是我拔掉DP线连接的显示器,即可正常进入bios。......