java aio和nio的区别

2023-11-15

AIO 是彻底的异步通信。
NIO 是同步非阻塞通信。
有一个经典的举例。烧开水。
假设有这么一个场景,有一排水壶(客户)在烧水。

AIO的做法是,每个水壶上装一个开关,当水开了以后会提醒对应的线程去处理。
NIO的做法是,叫一个线程不停的循环观察每一个水壶,根据每个水壶当前的状态去处理。
BIO的做法是,叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。

可以看出AIO是最聪明省力,NIO相对省力,叫一个人就能看所有的壶,BIO最愚蠢,劳动力低下。

简单的描述一下BIO的服务端通信模型:采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理 处理完成后,通过输出流返回应答给客户端,线程销毁。即典型的一请求一应答通宵模型。

01

刚开始人们为了解决上面,高并发下服务器建立线程过多而枯竭,有人就想出了使用线程池来控制建立线程的数量,不至于服务器挂掉,于是就有了伪异步的io编程

一(1)、伪异步I/O编程

  为了改进上面这种一连接一线程的模型,我们可以使用线程池来管理这些线程,实现1个或多个线程处理N个客户端的模型(但是底层还是使用的同步阻塞I/O),通常被称为“伪异步I/O模型“。

02

 我们知道,如果使用CachedThreadPool线程池(不限制线程数量),其实除了能自动帮我们管理线程(复用),看起来也就像是1:1的客户端:线程数模型,而使用FixedThreadPool我们就有效的控制了线程的最大数量,保证了系统有限的资源的控制,实现了N:M的伪异步I/O模型。

 但是,正因为限制了线程数量,如果发生大量并发请求,超过最大数量的线程就只能等待,直到线程池中的有空闲的线程可以被复用。而对Socket的输入流就行读取时,会一直阻塞,直到发生:

有数据可读

可用数据以及读取完毕

发生空指针或I/O异常

所以在读取数据较慢时(比如数据量大、网络传输慢等),大量并发的情况下,其他接入的消息,只能一直等待,这就是最大的弊端。而后面即将介绍的NIO,就能解决这个难题。

 二、NIO 编程(非阻塞I/O)

JDK 1.4中的java.nio.*包中引入新的Java I/O库,其目的是提高速度。实际上,“旧”的I/O包已经使用NIO重新实现过,即使我们不显式的使用NIO编程,也能从中受益。速度的提高在文件I/O和网络I/O中都可能会发生,但本文只讨论后者。

(1)缓冲区buffer

    buffer是一个对象,包含了读取和写入的数据,在nio中,所有的数据都是通过缓冲区来处理的。在写入数据时,也是写入到缓冲区中。任何时候访问NIO中的数据,都是通过缓冲区进行操作。

    缓冲区实际是一个数组结构,并提供了对数据结构化访问以及维护读写位置等信息。

    8种基本类型都有相应的缓冲区:ByteBuffe、CharBuffer、 ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。他们实现了相同的接口:Buffer。

(2)通道channel

    我们对数据的读取和写入都要通过channel,它就像水管一样,是一个通道。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。

    底层的操作系统的通道一般都是全双工的,所以全双工的Channel比流能更好的映射底层操作系统的API。

    channel主要有2大类:

       selectablechannel 用于用户网络的读写(后面代码会涉及的ServerSocketChannel和SocketChannel都是SelectableChannel的子类。)

       Filechannel 用于文件的操作

(3)多路复用器 Selector

    Selector是Java  NIO 编程的基础。

   提供选择已经就绪的任务的能力:Selector会不断轮询注册在其上的Channel,如果某个Channel上面发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以获取就绪Channel的集合,进行后续的I/O操作。

   一个Selector可以同时轮询多个Channel,因为JDK使用了epoll()代替传统的select实现,所以没有最大连接句柄1024/2048的限制。所以,只需要一个线程负责Selector的轮询,就可以接入成千上万的客户端。

(4)NIO服务端

  创建NIO服务端的主要步骤如下:

 

  1.   打开ServerSocketChannel,监听客户端连接
  2.  绑定监听端口,设置连接为非阻塞模式
  3.  创建Reactor线程,创建多路复用器并启动线程
  4.  将ServerSocketChannel注册到Reactor线程中的Selector上,监听ACCEPT事件
  5.  Selector轮询准备就绪的key
  6.  Selector监听到新的客户端接入,处理新的接入请求,完成TCP三次握手,简历物理链路
  7.  设置客户端链路为非阻塞模式
  8.  将新接入的客户端连接注册到Reactor线程的Selector上,监听读操作,读取客户端发送的网络消息
  9.  异步读取客户端消息到缓冲区
  10.  对Buffer编解码,处理半包消息,将解码成功的消息封装成Task
  11.  将应答消息编码为Buffer,调用SocketChannel的write将消息异步发送给客户端

    所以不能保证一次能吧需要发送的数据发送完,此时就会出现写半包的问题。我们需要注册写操作,不断轮询Selector将没有发送完的消息发送完毕,然后通过Buffer的hasRemain()方法判断消息是否发送完成。

(5)NIO客户端

三、AIO编程

   NIO 2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。

异步的套接字通道时真正的异步非阻塞I/O,对应于UNIX网络编程中的事件驱动I/O(AIO)。他不需要过多的Selector对注册的通道进行轮询即可实现异步读写,从而简化了NIO的编程模型。

API比NIO的使用起来真的简单多了,主要就是监听、读、写等各种CompletionHandler。此处本应有一个WriteHandler的,确实,我们在ReadHandler中,以一个匿名内部类实现了它。

AIO是真正的异步非阻塞的,所以,在面对超级大量的客户端,更能得心应手

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java aio和nio的区别 的相关文章

  • Java nio WatchService 用于多个目录

    我想使用 Java NIO 观看 监视 多个目录WatchService https docs oracle com javase 7 docs api java nio file WatchService html 我的问题是要观看的目录
  • Java 7 新的 IO API - Paths.exists [重复]

    这个问题在这里已经有答案了 有谁知道发生了什么事path exists 最新的Java 7 API中的API方法 我在更改日志中找不到更改 并且在 b123 和 b130 之间 该方法已从 API 中删除 我看到有一个静态Files exi
  • java.nio.file.FileAlreadyExistsException如何在java7中解决这个问题

    我正在编写代码 我正在使用 java nio api 创建一个目录 我的代码段是 Path target Paths get folder path xx 0 Set
  • NIO getParentFile().mkdir() [重复]

    这个问题在这里已经有答案了 有没有一种方法可以一次性创建文件和目录 如下所示 使用 Java 7 和 NIO 路径和文件静态方法 在哪里您不必键入路径 然后将文件分成单独的行 代码 File file new File Library te
  • 读取从 FileChannel 到 Stream of strings 的所有行

    对于我的特定任务 我需要从中读取数据FileChannel to a Stream or Collection of String s 在常规的NIO for a Path我们可以使用一个方便的方法Files lines 它返回一个Stre
  • 如何从 java.nio.Path 获取路径字符串?

    使用更多信息重写问题 我有一些代码可以创建Path使用相对路径的对象 如下所示 Paths get folder resolve filename 后来 我想从中获取路径字符串 folder filename 我在Windows上 所以有反
  • 为什么Java NIO专门引入Buffer类而不是使用数组?

    有人问我一个问题 为什么字节数组不够用 NIO专门引入了一个类Buffer 这个问题的好答案是什么 它只是一种简化读 写操作的包装类吗 如果可能的话 请给我们举个例子来说明我们如何从中受益Buffer不能 很难用数组完成的类 None
  • 为什么Java NIO可以优于标准Java套接字?

    最近我正在使用 Java 套接字和 NIO 来编写服务器 尽管我仍然不太清楚为什么 Java NIO 优于标准套接字 当使用这些技术之一编写服务器时 在大多数情况下 它归结为具有一个接受连接并将其进一步传递给工作线程的调度程序线程 我读过
  • java.io.NotSerializedException:sun.nio.fs.WindowsPath - 如何修复它?

    我编写了一个简单的序列化函数来存储 fileTree 表示 基于复合模式 但总是出现以下错误 java io NotSerializableException sun nio fs WindowsPath 不幸的是 到目前为止我还不知道如何
  • 我应该对 UDP 使用(非阻塞)NIO 吗?

    根据这个帖子 https stackoverflow com questions 569555 non blocking udp i o vs blocking udp i o in java UDP 只是不阻塞 使用 非阻塞 NIO AP
  • 使用 Netty 的异步 HTTP 客户端

    我是 Netty 新手 仍在努力寻找自己的方法 我正在寻找创建一个异步工作的 http 客户端 http的netty例子只展示了如何等待IO操作 并没有展示如何使用添加监听器 所以最近几天我一直在努力解决这个问题 我正在尝试创建一个请求类
  • 哪些文件系统支持 Java UserDefinedFileAttributeView?

    我需要用文件系统中的文件存储自定义数据 每个文件大约 50 个字节 我没有任何其他存储来保存数据 并且无法为此创建额外的文件 这些是我的要求我无法改变它 我发现这可以使用 UserDefinedFileAttributeView 类来完成
  • 为什么JDK NIO使用这么多anon_inode文件描述符?

    我正在使用 Sun 的 JDK 1 6 0 26 和 NIO 带有 Netty 在 lsof 中我看到数百个文件描述符anon inode lsof np 11225 fgrep w anon inode java 11225 nobody
  • 让Java文件传输更高效

    我有两台无线计算机连接到 N 个无线路由器 每台 PC 的连接速度都在 108 150Mbps 之间 理论上 在绝对最佳的条件下 我应该能够以 13 5MB s 到 18 75MB s 的速度传输 第一台计算机 正在发送 使用非常快的 SS
  • java.nio.file.Files.delete(Path path) - 使用 SimpleFileVisitor 递归删除目录偶尔失败

    尝试解决偶尔出现的问题java nio file DirectoryNotEmptyException在递归删除方法中取自Java中递归删除目录 https stackoverflow com questions 779519 delete
  • 即使没有来自客户端的连接,选择器也会无限循环

    我是 Java NIO 的新手 在阅读了一些教程后 我尝试自己编写一个简单的 NIO 服务器和客户端 我的服务器只做了一件简单的事情 就是从客户端监听并打印到控制台 客户端只需连接到服务器并向其发送 3 条消息 Hello 问题是我的服务器
  • 在 zip 中写入(修改或添加)文件

    我已按照中的说明进行操作这个线程 https stackoverflow com questions 13787318 java util zip replace a single zip file 使用其中的代码 我已经能够将文件添加到
  • 如何在Java NIO中配置socks代理

    我正在开发一个工具 其中包括强制应用程序的所有网络流量通过Java中的socks代理 对于旧的 Socket API 我只需设置系统属性 DsocksProxyHost my host DsocksProxyPort my port 但它不
  • java中监视目录变化

    我正在使用 WatchService 来监视目录中的更改 特别是目录中新文件的创建 下面是我的代码 package watcher import java nio file import static java nio file Stand
  • 为什么Java中的FileChannel不是非阻塞的?

    我想编写一个同时写入多个文件的程序 认为通过使用非阻塞模式可以用一个线程来实现 但FileChannel不支持非阻塞模式 有人知道为什么吗 UNIX 不支持文件的非阻塞 I O 请参阅常规文件的非阻塞 I O http www remlab

随机推荐

  • 小游戏:推箱子与推箱子简化版

    在第一版的代码中 将人在目标点上以及箱子在目标点上另外输出 在后续的获取方向键并处理时 只需减去人和箱子的数字就可以刷新目标点的显示 不会出现 吃 目标点的情况 而在第二版的代码中 使用偏移值的改变来简化代码 只需通过方向键的按键活动来改变
  • STL--set容器

    目录 一 set容器基本概念 二 set构造和赋值 三 set 大小和交换 四 set 插入和删除 五 set 查找和统计 六 set 和 multiset 的区别 七 set 容器排序 八 set 容器自定义类型数据排序 一 set容器基
  • chatgpt赋能python:用Python计算数学题,速度快效果好!

    用Python计算数学题 速度快效果好 在现代化的信息时代 计算机已经成为了我们生活中不可缺少的工具之一 而对于数学爱好者来说 用计算机进行数学计算已经变得非常普遍 因为使用计算机能够快速解决数学难题 同时也将复杂的计算变得更加简单易行 P
  • 分页组件

    分页组件是web开发中常见的组件 请完成pagination函数 在id为jsPagination的DOM元素中完成分页的显示部分 需求如下 1 最多连续显示5页 居中高亮显示current页 如demo1所示 2 total为0时 隐藏整
  • Java无法通过形参设置为null改变实参

    文章目录 问题描述 问题例子 问题分析 问题描述 在实际业务开发过程中 我们会把实参传递给形参 在方法体内对引用对象进行构建或者修改 从而改变实参 因为对形参对象属性修改时 实参对象也会随着改变 详情请看 Java是值传递还是引用传递 区别
  • Csharp: 阴历年甲子干支算法錯誤問題

  • 探索OLED透明屏的优缺点:引领科技未来的革命性突破

    OLED透明屏作为一项革命性的创新技术 其令人惊叹的透明度和柔性性能引起了全球范围内的关注 然而 了解OLED透明屏的优缺点对于我们全面认识其在科技未来中的地位至关重要 今天 尼伽将深入探讨OLED透明屏的优势和限制 并借助相关数据 报告和
  • 什么是802.11无线局域网(WLAN)标准?

    Wireless technologies are the center of daily life Wireless networks are used to transfer data between different devices
  • 再见 Xshell ,这款开源的终端工具逼格更高

    再见 Xshell 这款开源的终端工具逼格更高 作为一名后端开发 我们经常需要和Linux系统打交道 免不了要使用Xshell这类终端工具来进行远程管理 最近发现一款更炫酷的终端工具Tabby 主题丰富 功能强大 推荐给大家 SpringB
  • Java NIO——通道Channel:网络Channel通信(重点)

    目录 IO的阻塞与非阻塞 NIO网络通信 没有使用Selector的阻塞NIO通信 非阻塞NIO通信 重点 Selector Channel 注册到 Selector 选择键 SelectionKey Selector的使用方法 IO的阻塞
  • UNeXT

    论文链接 https link springer com chapter 10 1007 978 3 031 16443 9 3 源码链接 https github com jeya maria jose UNeXt pytorch 论文摘
  • linnux系统常用命令

    shutdown h now 立刻进行关机 shutdown r now 现在重新启动计算机 reboot 现在重新启动计算机 su 切换用户 passwd 修改用户密码 logout 用户注销 tab 补全 ctrl l 清屏 类似cle
  • 49个Python的常见操作/技巧/例子

    17个Python的常见操作 技巧 很多读者都知道 Python 是一种高级编程语言 其设计的核心理念是代码的易读性 以及允许编程者通过若干行代码轻松表达想法创意 实际上 很多人选择学习 Python 的首要原因是其编程的优美性 用它编码和
  • 《pigcms v6.2最新完美至尊版无任何限制,小猪微信源码多用户微信营销服务平台系统》

    pigcms v6 2最新完美至尊版无任何限制 小猪微信源码多用户微信营销服务平台系统 前两天分享了套小猪CMS PigCms 多用户微信营销服务平台系统V6 1完美破解至尊版带微用户管理CRM 微信支付 还是不少童鞋反应出不少问题 今天再
  • unity-障碍物和空气墙的设置

    文章目录 建立空气墙 建立空气墙 建个游戏对象 然后给他添加2d碰撞盒子属性 把它放到相机下面 让它成为相机的所属的子组 跟随相机一起移动通过 创建新的标签便于碰撞确认操作 判断我们游戏操控的物体是否在空气墙上 判断是否处于空气墙上面 pr
  • 每日必看的五个产品科技类网站?

    1 Github 看看 GitHub 社区今天最热门的是什么 https github com trending 2 v2ex 会有一些新的互联网产品发布在这里 偶尔会附带免费的激活码 3 producthunt 看看今天有什么新的创业产品
  • Maven Pom设置简单项目打jar包时的入口类

    Maven Pom设置简单项目打jar包时的入口类 有时 不使用框架的简单的项目也要以jar包的形式发布和使用 如果不知道如何在pom中设置项目的入口类 就比较麻烦 在pom文件中添加如下代码 就可以设置项目的入口类了 当然 入口类中要有m
  • miniconda的安装和python环境搭建

    文章目录 前言 下载minianaconda 安装和配置 安装注意 配置 更改镜像源 创建虚拟环境和激活 conda常用指令 前言 最近想用python去写一个写ini配置文件的工具 由于电脑现在的环境是python2的 想用python3
  • AES加密出现Error: Malformed UTF-8 data报错的解决方法

    按我上一章 vue java 使用AES 前后端加密解密 址址 https blog csdn net weixin 42124196 article details 88416488 文章进行aes加密的项目 当页面获取数据时一直出现Er
  • java aio和nio的区别

    AIO 是彻底的异步通信 NIO 是同步非阻塞通信 有一个经典的举例 烧开水 假设有这么一个场景 有一排水壶 客户 在烧水 AIO的做法是 每个水壶上装一个开关 当水开了以后会提醒对应的线程去处理 NIO的做法是 叫一个线程不停的循环观察每