aio 系统原理 Java_Java新一代网络编程模型AIO原理及Linux系统AIO介绍

从JDK 7版本开始,Java新加入的文件和网络io特性称为nio2(new io 2, 因为jdk1.4中已经有过一个nio了),包含了众多性能和功能上的改进,其中最重要的部分,就是对异步io的支持,称为Java AIO(asynchronous IO)。

因为AIO的实施需充分调用OS参与,IO需要操作系统支持、并发也同样需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。所以本文也附带介绍了Linux 2.6及以后版本新增的AIO特性(因为这跟Java AIO是对应关系)。

Java AIO

1基本原理

目前为止,Java共支持3种网络编程模型:BIO、NIO、AIO:

Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

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

Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

BIO、NIO、AIO适用场景分析:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

2AIO介绍

jdk在1.4版本的nio中提供了对非阻塞多路复用同步io模型的支持,但是在Windows上是基于较低效select/poll实现的。

jdk1.7中提供对aio的支持后,带来了两方面的好处:

Windows上可以使用iocp了。

简化了网络变成模型。异步io相比较非阻塞多路复用模型更易理解,开发更为简单。

和多路复用的java nio相比较,可以发现,异步io是在数据读取或者写入调用已经完成的时候,再通知调用者,而非阻塞多路复用io则是在有数据就绪,可以读写的时候通知调用者,读写仍然是由调用者执行并且是阻塞的(这意味着如果要同时进行其他工作,要控制读写操作不能阻塞太长时间或者需要将其放去单独的io线程执行)。

JDK7中的java aio新增的类和接口主要有:

AsynchronousServerSocketChannel ,对应于bio中的ServerSocket和nio中的ServerSocketChannel,用于server端的网络程序。

AsynchronousSocketChannel,对云关于bio中的Socket和nio中的SocketChannel,用于client端的网络程序。

CompletionHandler,回调接口,在socket进行accept/connect/read/write等操作时,可以传入一个CompletionHandler的实现,操作执行完毕后,会调用注册的CompletionHandler。

除了CompletionHandler这种回调方式,aio中还支持返回Future对象,使用Future来设定回调操作。

Linux AIO

1Linux AIO 简介

Linux 异步 I/O 是 Linux 内核中提供的一个相当新的增强。它是 2.6 版本内核的一个标准特性,但是我们在 2.4 版本内核的补丁中也可以找到它。AIO 背后的基本思想是允许进程发起很多 I/O 操作,而不用阻塞或等待任何操作完成。稍后或在接收到 I/O 操作完成的通知时,进程就可以检索 I/O 操作的结果。

2Linux 的 I/O 模型

在深入介绍 AIO API 之前,让我们先来探索一下 Linux 上可以使用的不同 I/O 模型。这并不是一个详尽的介绍,但是我们将试图介绍最常用的一些模型来解释它们与异步 I/O 之间的区别。图 1 给出了同步和异步模型,以及阻塞和非阻塞的模型。

基本 Linux I/O 模型的简单矩阵:

每个 I/O 模型都有自己的使用模式,它们对于特定的应用程序都有自己的优点。

同步阻塞 I/O:

如下图所示:传统的阻塞 I/O 模型,这也是目前应用程序中最为常用的一种模型。其行为非常容易理解,其用法对于典型的应用程序来说都非常有效。在调用 read 系统调用时,应用程序会阻塞并对内核进行上下文切换。然后会触发读操作,当响应返回时(从我们正在从中读取的设备中返回),数据就被移动到用户空间的缓冲区中。然后应用程序就会解除阻塞(read 调用返回)。

从应用程序的角度来说,read 调用会延续很长时间。实际上,在内核执行读操作和其他工作时,应用程序的确会被阻塞。

同步非阻塞 I/O:

同步阻塞 I/O 的一种效率稍低的变种是同步非阻塞 I/O。在这种模型中,设备是以非阻塞的形式打开的。这意味着 I/O 操作不会立即完成,read 操作可能会返回一个错误代码,说明这个命令不能立即满足(EAGAIN 或 EWOULDBLOCK),如下图所示。

非阻塞的实现是 I/O 命令可能并不会立即满足,需要应用程序调用许多次来等待操作完成。这可能效率不高,因为在很多情况下,当内核执行这个命令时,应用程序必须要进行忙碌等待,直到数据可用为止,或者试图执行其他工作。正如图 3 所示的一样,这个方法可以引入 I/O 操作的延时,因为数据在内核中变为可用到用户调用 read 返回数据之间存在一定的间隔,这会导致整体数据吞吐量的降低。

异步阻塞 I/O:

另外一个阻塞解决方案是带有阻塞通知的非阻塞 I/O。在这种模型中,配置的是非阻塞 I/O,然后使用阻塞 select 系统调用来确定一个 I/O 描述符何时有操作。使 select 调用非常有趣的是它可以用来为多个描述符提供通知,而不仅仅为一个描述符提供通知。对于每个提示符来说,我们可以请求这个描述符可以写数据、有读数据可用以及是否发生错误的通知。

select 调用的主要问题是它的效率不是非常高。尽管这是异步通知使用的一种方便模型,但是对于高性能的 I/O 操作来说不建议使用。

异步非阻塞 I/O(AIO):

最后,异步非阻塞 I/O 模型是一种处理与 I/O 重叠进行的模型。读请求会立即返回,说明 read 请求已经成功发起了。在后台完成读操作时,应用程序然后会执行其他处理操作。当 read 的响应到达时,就会产生一个信号或执行一个基于线程的回调函数来完成这次 I/O 处理过程。

在一个进程中为了执行多个 I/O 请求而对计算操作和 I/O 处理进行重叠处理的能力利用了处理速度与 I/O 速度之间的差异。当一个或多个 I/O 请求挂起时,CPU 可以执行其他任务;或者更为常见的是,在发起其他 I/O 的同时对已经完成的 I/O 进行操作。

3异步 I/O(AIO) 的动机

从前面 I/O 模型的分类中,我们可以看出 AIO 的动机。这种阻塞模型需要在 I/O 操作开始时阻塞应用程序。这意味着不可能同时重叠进行处理和 I/O 操作。同步非阻塞模型允许处理和 I/O 操作重叠进行,但是这需要应用程序根据重现的规则来检查 I/O 操作的状态。这样就剩下异步非阻塞 I/O 了,它允许处理和 I/O 操作重叠进行,包括 I/O 操作完成的通知。

除了需要阻塞之外,select 函数所提供的功能(异步阻塞 I/O)与 AIO 类似。不过,它是对通知事件进行阻塞,而不是对 I/O 调用进行阻塞。

总结

使用异步 I/O(AIO)可以帮助我们构建 I/O 速度更快、效率更高的应用程序。如果我们的应用程序可以对处理和 I/O 操作重叠进行,那么 AIO 就可以帮助我们构建可以更高效地使用可用 CPU 资源的应用程序。

尽管这种 I/O 模型与在大部分 Linux 应用程序中使用的传统阻塞模式都不同,但是异步通知模型在概念上来说却非常简单,可以简化我们的设计。

2dc05a685c1d1acfbcc069fad41c07dd.png 

9020c1aa11fd5dbf3a09f25eb4581c44.png 

1e325f4e3b217355a8b0cf98ecff82bb.png 

9c64b40c260c4ed24713d4b61a92b5b4.png 

4756e4d07731ca3cab1dda5118136756.png 

76c0329d9d8ceb96ab15958765f9d8d2.png 

b5aa4220b58c50467cb162378e808829.png 

6c4fcb3a1f9f588869e1bf11cfa40f67.png

81112651b0ac7a92e4c84c51aafb04fc.png 

c31afdba555b9a64f35b9b01d8203cab.png 

4189155ecc55866d69b4ea43d283a5ab.png 

0f6ab8084fe96dcef884f2ad75dfa73a.png 

89ea900190b8a5a3b2f12c524b7b4c72.png 

dd01fcf08cead9d890a2df13ee784ff3.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533050.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos mysql 5.5 art_Linux CentOS6.5下编译安装MySQL 5.5.51''''

一、编译安装MySQL前的准备工作安装编译源码所需的工具和库yum install gcc gcc-c ncurses-devel perl安装cmake,从http://www.cmake.org下载源码并编译安装wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gztar -xzvf cmake-2.8.10.2.tar.gzcd cmake-2.…

java修改默认字符编码_设置默认的Java字符编码?

如何以编程方式正确设置JVM(1.5.x)使用​​的默认字符编码?我已经读过-Dfile.encoding 以前是以往的方式去为旧的JVM …我没有那么奢侈的原因,我不会进入。我努力了:System.setProperty("file.encoding", "UTF-8");并且属…

java api 第一个类是_JAVA常用API:String 类的常用方法

字符串是一个对象,有很多方法可以使用1. length();返回字符串的长度String str "abcd";int len str.length();2. isEmpty(); 仅当当length()为0时返回true,否则返回falseboolean b str.isEmpty();3. getBytes();返回字符串中每个字符的ASCII码(使用平台…

关于java内容_关于java一些概念性的内容

PO:persistant object持久对象最形象的理解就是一个PO就是数据库中的一条记录。好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。--------------------------------------------------------------------------------BO:busin…

java订单类_基于Java创建一个订单类代码实例

这篇文章主要介绍了基于Java创建一个订单类代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下需求描述定义一个类,描述订单信息订单id订单所属用户(用户对象)订单所包含的商品(不定数量个商品对…

java请假审批怎么实现_java实现请假时间判断

笔记:需求分析:每周上班6天夏季早上8:30-12:00下午14:00-17:30冬季早上8:30-12:00下午14:30-18:00请假最低为半天按照上午8:00-12:00,下午14:00-18:00计算,包括了夏季和冬季时间,规律分布如下public String getDouble(HttpServletRequest request) throws ParseException {//参…

mariadb mysql 5.6_MySQL / MariaDB 5.5 升级到 MySQL 5.6

RHEL 及 CentOS 7 默认的资库系统是 MariaDB 5.5 (等同 MySQL 5.5), 虽然现时 MySQL 最新版是 5.7, 但一般上升级都建议一级一级上, 而 MySQL 5.6 比 5.5 也提高了效能及提供更多功能, 以下是在 RHEL 及 CentOS 从原来的 MySQL 5.5 或 MariaDB 5.5, 升级到 MySQL 5.6 的步骤。1…

iText报表Java_(例)Java生成PDF报表 iText

// 导入IO库类import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;// 导入 PO&#x…

mysql update修改数据_MySQL UPDATE:修改数据(更新数据)

在 MySQL 中,可以使用 UPDATE 语句来修改、更新一个或多个表的数据。UPDATE 语句的基本语法使用 UPDATE 语句修改单个表,语法格式为:UPDATE SET 字段 1值 1 [,字段 2值 2… ] [WHERE 子句 ][ORDER BY 子句] [LIMIT 子句]语法说明如下&#xf…

java堆内存 数据结构_JAVA内存区域

首先解释下内存溢出和内存泄露之间的区别,为后面的学习做些铺垫:1、内存溢出和内存泄露的区别和联系内存溢出 out of memory:是指程序申请内存时,没有足够的内存供申请者使用,或者说,给了你一块存储int类型…

java jsp的指令_[javaEE] jsp的指令

jsp的指令:jsp的指令(directive)是为jsp引擎而设计的,他们并不直接产生任何可见输出,而是告诉引擎如何处理jsp页面中的其他部分页面头部的page指令pageEncoding"utf-8"%>配置错误页面:web.xml500/500.jsp404/404.jsp…

JAVA不能满屏_java – 全屏幕视频,不拉伸视频

像这样,你可以自己设置视频的属性。使用SurfaceView(给你更多的视图控制),将其设置为fill_parent以匹配整个屏幕android:orientation"vertical"android:layout_width"match_parent"android:layout_height"fill_parent">…

java异常标记_java.lang.RuntimeException:错误:0D0680A8:asn1编码例程:ASN1_CHECK_TLEN:错误的标记...

我收到此错误(在标题中).我不确定为什么,请帮忙.代码如下:public static String decryptRSA(Context mContext, byte[] message) throws Exception {InputStream in mContext.getResources().openRawResource(R.raw.publicrsakey);X509EncodedKeySpec x509EncodedK…

正版我的世界怎么下载java_mcjava正版下载-mc我的世界java安卓正式版极速下载v1.0.1 - 趣趣手游网...

mc我的世界java安卓正式版带你体验最为精彩的多人联机对战玩法,游戏专为java系列打造,在游戏的部分特性上有着各种的提升,以及各种专属的表达,比基岩版能多一些不同的玩法,在这里有着各种不同的玩法以及模式等待你的加…

java原子整数_多线程(四、原子类-AtomicInteger)

案例10个线程并发累加一个整数,每个线程累加1000,保证线程安全Unsafe类,来源于sun.misc包。该类封装了许多类似指针操作,可以直接进行内存管理、操纵对象、阻塞/唤醒线程等操作。package com.jane;import java.util.ArrayList;imp…

java 新建菜单选项_请完成下列Java程序:创建一个下拉式菜单,菜单项包括3个CheckboxM..._考试资料网...

请完成下列Java程序:创建一个下拉式菜单,菜单项包括3个CheckboxMenultem(复选框),一条分割线和一个Exit项。要求打开或关闭复选框时,确定是哪个被切换,是开还是关,并输出它的状态;选择Exit项能够…

adurnio 单片机_单片机20~200A大电流检测电路设计 用AD实现 带原理图,源代码,proteus仿真文件...

//------------------------------51单片机头文件#include//各数字的数码管段码(共阴)unsigned char code DSY_CODE[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管显示数组{0,1,2,3,4,5,6,7,8,9}sbit CLKP3^3; //时钟信号sbit STP3^6; //启动信号,由…

java 极客_Java极客思维

​开篇介绍大家好,公众号【Java极客思维】近期会整理一些Java高频面试题分享给小伙伴,也希望看到的小伙伴在找工作过程中能够用得到!本章节主要针对Java一些消息中间件高频面试题进行分享。通知:公众号【Java极客思维】正在送书福…

java拼三级魔方_魔方秘籍(详细解法)《三阶》

魔方根据视频理解:上 下 左 右先将白面变好:(1).变一个白十字(如图所示)(2).转好以后检查十字的四个角的颜色(蓝绿红橙)与旁边面上的中心块的颜色是否相同。(有两个相同的时,如果它们相邻,就一个放在后面,一个放在左面…

php怎么实现点卡充值,利用自动发卡程序的点卡充值传奇脚本

首先:自动售卡 玩家购买到卡密 在游戏输入卡密领取元宝下面是NPC脚本:[main]!这里是点卡充值平台!\\\ \ \\[InPutString18]#IFCHECKCODELIST ..\QuestDiary\卡号列表\5.txt#actCLEARCODELIST ..\QuestDiary\卡号列表\5.txtGAMEGOL…