JAVA AIO

Reactor与Proactor reactor,proactor 阅读详情
转载 Reactor and Proactor的内容

系统I/O 可分为阻塞型, 非阻塞同步型以及非阻塞异步型[1, 2]. 阻塞型I/O意味着控制权只到调用操作结束了才会回到调用者手里. 结果调用者被阻塞了, 这段时间了做不了任何其它事情. 更郁闷的是,在等待IO结果的时间里,调用者所在线程此时无法腾出手来去响应其它的请求,这真是太浪费资源了。拿read()操作来说吧, 调用此函数的代码会一直僵在此处直至它所读的socket缓存中有数据到来.

相比之下,非阻塞同步是会立即返回控制权给调用者的。调用者不需要等等,它从调用的函数获取两种结果:要么此次调用成功进行了;要么系统返回错误标识告诉调用者当前资源不可用,你再等等或者再试度看吧。比如read()操作, 如果当前socket无数据可读,则立即返回EWOULBLOCK/EAGAIN,告诉调用read()者"数据还没准备好,你稍后再试".

在非阻塞异步调用中,稍有不同。调用函数在立即返回时,还告诉调用者,这次请求已经开始了。系统会使用另外的资源或者线程来完成这次调用操作,并在完成的时候知会调用者(比如通过回调函数)。拿Windows的ReadFile()或者POSIX的aio_read()来说,调用它之后,函数立即返回,操作系统在后台同时开始读操作。

在以上三种IO形式中,非阻塞异步是性能最高、伸缩性最好的。

这篇文章探讨不同的I/O利用机制并提供一种跨平台的设计模式(解决方案). 希望此文可以给于TCP高性能服务器开发者一些帮助,选择最佳的设计方案。下面我们会比较 Java, c#, C++各自对探讨方案的实现以及性能. 我们在文章的后面就不再提及阻塞式的方案了,因为阻塞式I/O实在是缺少可伸缩性,性能也达不到高性能服务器的要求。

两种IO多路复用方案:Reactor and Proactor

一般情况下,I/O 复用机制需要事件分享器(event demultiplexor [1, 3]). 事件分享器的作用,即将那些读写事件源分发给各读写事件的处理者,就像送快递的在楼下喊: 谁的什么东西送了, 快来拿吧。开发人员在开始的时候需要在分享器那里注册感兴趣的事件,并提供相应的处理者(event handlers),或者是回调函数; 事件分享器在适当的时候会将请求的事件分发给这些handler或者回调函数.

涉及到事件分享器的两种模式称为:Reactor and Proactor [1]. Reactor模式是基于同步I/O的,而Proactor模式是和异步I/O相关的. 在Reactor模式中,事件分离者等待某个事件或者可应用或个操作的状态发生(比如文件描述符可读写,或者是socket可读写),事件分离者就把这个事件传给事先注册的事件处理函数或者回调函数,由后者来做实际的读写操作。

而在Proactor模式中,事件处理者(或者代由事件分离者发起)直接发起一个异步读写操作(相当于请求),而实际的工作是由操作系统来完成的。发起时,需要提供的参数包括用于存放读到数据的缓存区,读的数据大小,或者用于存放外发数据的缓存区,以及这个请求完后的回调函数等信息。事件分离者得知了这个请求,它默默等待这个请求的完成,然后转发完成事件给相应的事件处理者或者回调。举例来说,在Windows上事件处理者投递了一个异步IO操作(称有overlapped的技术),事件分离者等IOCompletion事件完成[1]. 这种异步模式的典型实现是基于操作系统底层异步API的,所以我们可称之为“系统级别”的或者“真正意义上”的异步,因为具体的读写是由操作系统代劳的。

举另外个例子来更好地理解Reactor与Proactor两种模式的区别。这里我们只关注read操作,因为write操作也是差不多的。下面是Reactor的做法:

  • 某个事件处理者宣称它对某个socket上的读事件很感兴趣;
  • 事件分离者等着这个事件的发生;
  • 当事件发生了,事件分离器被唤醒,这负责通知先前那个事件处理者;
  • 事件处理者收到消息,于是去那个socket上读数据了. 如果需要,它再次宣称对这个socket上的读事件感兴趣,一直重复上面的步骤;

下面再来看看真正意义的异步模式Proactor是如何做的:

  • 事件处理者直接投递发一个写操作(当然,操作系统必须支持这个异步操作). 这个时候,事件处理者根本不关心读事件,它只管发这么个请求,它魂牵梦萦的是这个写操作的完成事件。这个处理者很拽,发个命令就不管具体的事情了,只等着别人(系统)帮他搞定的时候给他回个话。
  • 事件分离者等着这个读事件的完成(比较下与Reactor的不同);
  • 当事件分离者默默等待完成事情到来的同时,操作系统已经在一边开始干活了,它从目标读取数据,放入用户提供的缓存区中,最后通知事件分离者,这个事情我搞完了;
  • 事件分享者通知之前的事件处理者: 你吩咐的事情搞定了;
  • 事件处理者这时会发现想要读的数据已经乖乖地放在他提供的缓存区中,想怎么处理都行了。如果有需要,事件处理者还像之前一样发起另外一个写操作,和上面的几个步骤一样。

jdk 7中已经内置了AIO的实现,可以参考 http://www.iteye.com/topic/472333 这个对aio的分析

我们试试jdk7的AIO的示例

服务器端程序


[java]  view plain copy
  1. import java.io.IOException;  
  2. import java.net.InetSocketAddress;  
  3. import java.nio.ByteBuffer;  
  4. import java.nio.channels.AsynchronousChannelGroup;  
  5. import java.nio.channels.AsynchronousServerSocketChannel;  
  6. import java.nio.channels.AsynchronousSocketChannel;  
  7. import java.nio.channels.CompletionHandler;  
  8. import java.util.concurrent.ExecutionException;  
  9. import java.util.concurrent.ExecutorService;  
  10. import java.util.concurrent.Executors;  
  11.   
  12.   
  13. public class EchoAioServer {  
  14.   
  15.     private final int port;  
  16.   
  17.     public static void main(String args[]) {  
  18.         int port = 8000;  
  19.         new EchoAioServer(port);  
  20.     }  
  21.   
  22.     public EchoAioServer(int port) {  
  23.         this.port = port;  
  24.         listen();  
  25.     }  
  26.   
  27.     private void listen() {  
  28.         try {  
  29.             ExecutorService executorService = Executors.newCachedThreadPool();  
  30.             AsynchronousChannelGroup threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);  
  31.             try (AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(threadGroup)) {  
  32.                 server.bind(new InetSocketAddress(port));  
  33.   
  34.                 System.out.println("Echo listen on " + port);  
  35.   
  36.                 server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {  
  37.                     final ByteBuffer echoBuffer = ByteBuffer.allocateDirect(1024);  
  38.                     public void completed(AsynchronousSocketChannel result, Object attachment) {  
  39.                         System.out.println("waiting ....");  
  40.                         try {  
  41.                             echoBuffer.clear();  
  42.                             result.read(echoBuffer).get();  
  43.                             echoBuffer.flip();  
  44.                             // echo data  
  45.                             result.write(echoBuffer);  
  46.                             echoBuffer.flip();  
  47. //                            System.out.println("Echoed '" + new String(echoBuffer.array()) + "' to " + result);  
  48.                         } catch (InterruptedException | ExecutionException e) {  
  49.                             System.out.println(e.toString());  
  50.                         } finally {  
  51.                             try {  
  52.                                 result.close();  
  53.                                 server.accept(null, this);  
  54.                             } catch (Exception e) {  
  55.                                 System.out.println(e.toString());  
  56.                             }  
  57.                         }  
  58.   
  59.                         System.out.println("done...");  
  60.                     }  
  61.   
  62.                     @Override  
  63.                     public void failed(Throwable exc, Object attachment) {  
  64.                         System.out.println("server failed: " + exc);  
  65.                     }  
  66.                 });  
  67.   
  68.                 try {  
  69.                     // Wait for ever  
  70.                     Thread.sleep(Integer.MAX_VALUE);  
  71.                 } catch (InterruptedException ex) {  
  72.                     System.out.println(ex);  
  73.                 }  
  74.             }  
  75.         } catch (IOException e) {  
  76.             System.out.println(e);  
  77.         }  
  78.     }  
  79. }  

客户端程序


[java]  view plain copy
  1. import java.net.InetSocketAddress;  
  2. import java.nio.ByteBuffer;  
  3. import java.nio.channels.AsynchronousSocketChannel;  
  4. import java.nio.channels.CompletionHandler;  
  5. import java.util.concurrent.ExecutionException;  
  6.   
  7. public class EchoAioClient {  
  8.     private final AsynchronousSocketChannel client ;  
  9.       
  10.     public EchoAioClient() throws Exception{  
  11.        client = AsynchronousSocketChannel.open();  
  12.     }  
  13.       
  14.     public void start()throws Exception{  
  15.         client.connect(new InetSocketAddress("127.0.0.1",8000),null,new CompletionHandler<Void,Void>() {  
  16.             @Override  
  17.             public void completed(Void result, Void attachment) {  
  18.                 try {  
  19.                     client.write(ByteBuffer.wrap("this is a test".getBytes())).get();  
  20.                     System.out.println("send data to server");  
  21.                 } catch (Exception ex) {  
  22.                     ex.printStackTrace();  
  23.                 }  
  24.             }  
  25.   
  26.             @Override  
  27.             public void failed(Throwable exc, Void attachment) {  
  28.                 exc.printStackTrace();  
  29.             }  
  30.         });  
  31.         final ByteBuffer bb = ByteBuffer.allocate(1024);  
  32.         client.read(bb, null, new CompletionHandler<Integer,Object>(){  
  33.   
  34.             @Override  
  35.             public void completed(Integer result, Object attachment) {  
  36.                  System.out.println(result);  
  37.                  System.out.println(new String(bb.array()));  
  38.             }  
  39.   
  40.             @Override  
  41.             public void failed(Throwable exc, Object attachment) {  
  42.                     exc.printStackTrace();  
  43.                 }  
  44.             }  
  45.         );  
  46.           
  47.   
  48.           
  49.         try {  
  50.             // Wait for ever  
  51.             Thread.sleep(Integer.MAX_VALUE);  
  52.         } catch (InterruptedException ex) {  
  53.             System.out.println(ex);  
  54.         }  
  55.           
  56.     }  
  57.       
  58.     public static void main(String args[])throws Exception{  
  59.         new EchoAioClient().start();  
  60.     }  
  61. }  

执行server跟client后输出如下:

server输出:

[html]  view plain copy
  1. Echo listen on 8000  
  2. waiting ....  
  3. done...  

client输出:
[html]  view plain copy
  1. send data to server  
  2. 14  
  3. this is a test  


Java AIO 阅读详情

相关推荐

Java AIO介绍及Netty移除AIO的原因

然而,由于平台兼容性、功能限制、异常处理复杂和性能稳定性等问题,Netty在4.x版本之后移除了对Java AIO的支持,并专注于基于Java NIO的实现,提供更全面、稳定和易用的网络框架。Java NIO(New I/O)是Java 1.4引入的一组新的I/O API,它提供了基于通道(Channel)和缓冲区(Buffer)的I/O操作方式。当有大量的连接需要处理时,每个连接都需要一个独立的线程来处理,因此线程的数量会随着连接的增加而急剧上升,从而导致线程资源的浪费。处理异步的连接操作。

BxuqBlockchain的博客 383

Proactor模式详解

  proactor结构模式在异步操作完成后触发服务请求的分配和分发 。 1. 举个例子吧   考虑一个需要同时处理多个请求的网络服务程序,比如,一个高效的WEB服务器需要并发的处理来自于不同客户端浏览器的HTTP请求。当一个用户希望从某个URL下载内容时,浏览器和WEB服务器建立连接并发送HTTP的GET请求。WEB服务器顺序执行了:接收浏览器的连接事件,接受连接请求,读取请求,然后解析请求...

ty的博客 1万+

游戏开发实战:如何用旋转矩阵实现2D角色平滑转向(附Unity代码)

本文深入探讨了在Unity游戏开发中,如何运用旋转矩阵原理实现2D角色的平滑转向。文章从核心理论出发,提供了计算目标旋转、实现平滑插值(Lerp与SmoothDamp)的完整C#代码,并解决了与动画系统、物理引擎协同的常见难题,帮助开发者提升游戏操作手感与视觉流畅度。

weixin_29057237的博客 287

Proactor模式专题

先来看看,当用户程序执行read,线程会被阻塞,一直等到内核数据准备好,并把数据从内核缓冲区拷贝到应用程序的缓冲区中,当拷贝过程完成,read才会返回。知道了阻塞 I/O ,来看看,非阻塞的 read 请求在数据未准备好的情况下立即返回,可以继续往下执行,此时应用程序不断轮询内核,直到数据准备好,内核将数据拷贝到应用程序缓冲区,read调用才可以获取到结果因此,无论 read 和 send 是阻塞 I/O,还是非阻塞 I/O。因为。

weixin_62827806的博客 353

Eclipse 数据空间组件(EDC)项目介绍

在当今数字经济的背景下,数据成为了新的“石油”。但与石油不同的是,数据可以无限共享且再生。然而,如何在保持数据主权的前提下实现高效、安全的数据共享,成为了企业和组织面临的主要挑战。这时,**Eclipse 数据空间组件(Eclipse Dataspace Components, EDC)**应运而生,它为企业在多方参与的数据交换中提供了一个标准化、可扩展的解决方案。数据空间不仅是一个多组织间的数据共享协议,还是一套支撑这些协议运行的技术基础设施。

m0_74331272的博客 4596

剪映自动化工具来了:AI帮你自动剪辑成片

🎬分享一个剪映自动化剪辑工具!AI 自动帮你完成从写文案、配音、加字幕、选音乐、上特效到最终导出的整套流程🎈

XiaoqiangClub的博客 855

proactor(前驱)模式

前驱模式(Proactor)是一种事件处理的软件设计模式,其中长时间运行的活动在异步部分中运行。当异步部分完成后调用相应的处理程序。

码上看世界 1495

uniapp中使用canvas生成海报,并下载保存到手机相册

如下图,是在H5中,canvas生成后的效果,首先说明,H5不支持返回图片的临时路径,不能用于保存,APP端生成成功后,会返回图片的临时路径用来保存到相册。本地测试,用的网络图片,没有出现跨域的问题,APP端也正常显示。 完整代码:可以将整个代码复制到你得uniapp项目中直接运行。代码中做了详细的注册,关于API的用法,这里只标注的简单的提示,具体还是参考 官方链接uniapp-canvas吧 <template> <view class="demo"> <c.

sunluyi的博客 3万+

【操作系统】高性能网络模式:Reactor 和 Proactor

【操作系统】高性能网络模式:Reactor 和 Proactor

blblccc 1606

【腾讯小龙虾 WorkBuddy 专栏 03】技能(Skills)制作全教程!自定义技能编写、导出分享、导入使用一步到位

🔥腾讯AI智能体WorkBuddy自定义技能全攻略 本文为零基础用户提供WorkBuddy自定义技能的完整教程,涵盖技能概念、编写规范到实操全流程。核心内容包括: 技能本质:标准化任务指令模板,可固化重复操作流程 三大价值:一键执行重复任务/跨设备共享/降低使用门槛 实操演示:以"桌面文档自动分类"为例,分步讲解编写、测试、导出 共享方案:支持单技能/批量导出,通过任意渠道传输分享 导入指南:3秒完成他人技能加载,并提供常见问题解决方案 高阶优化:增加异常处理、版本管理等提升技能普适性

AI人人懂 2944

黑猫带你学Nand第11篇:万字长文带你了解NandFlash的数据保持原理及特性(Data Retention)

TATTAT:Trap-assistedtunneling,陷阱辅助隧穿,也有叫法称为电荷陷阱现象。这是一种物理现象,它发生在非挥发性存储器,如NAND闪存。在这种效应中,存储在闪存单元浮动栅极上的电荷(电子)由于隧道氧化物中捕获的电荷形成的电场影响,导致电荷通过隧道效应从一个能级隧穿到另一个能级,从而造成电荷泄漏。这种电荷泄漏是导致闪存数据保持问题的主要原因之一,因为它可以改变存储在闪存单元中的电荷量,进而改变其阈值电压水平,最终可能导致数据错误。在NANDFlash中,电荷被存储在浮置栅极上。

黑猫奥利奥的博客 1095

java当中什么是AIO

AIO,全称为Asynchronous IO(异步输入输出),是Java中的一种处理I/O操作的方式,尤其在处理高并发、大量I/O请求时非常有效。AIO是Java NIO.2的一部分,是Java 7中引入的,用于改进NIO(Non-blocking IO,非阻塞输入输出)中的一些局限性。

Flying_Fish_roe的博客 2140

扩充两个三维体积:ITK实现

在医学图像处理中,经常需要进行 3D 体积的操作,比如合并、分割等。而 ITK (Insight Segmentation and Registration Toolkit) 是一个常用的开源库,可以用于实现各种医学图像处理算法。这篇文章将介绍如何使用 ITK 实现扩充两个三维体积的操作。不过以上代码已经足够简单明了地演示了如何使用 ITK 实现扩充两个三维体积的操作。首先,我们需要准备两个三维体积的数据。这里假设这两个体积大小相同,并且已经加载到内存中了。来读取和保存体积数据,使用了。

CodeVorter的博客 204

【Java】Java AIO使用详解

欢迎关注公众号: nullobject 。 文章首发在个人博客 https://www.nullobject.cn,公众号nullobject同步更新。 这篇文章主要讲解Java AIO网络编程。 1. AIO是什么 本文所说的AIO特指Java环境下的AIO。AIO是java中IO模型的一种,作为NIO的改进和增强随JDK1.7版本更新被集成在JDK的nio包中,因此AIO也被称作是NI...

NullObject 2803

Android日志实战——车机日志获取(十五)

这个项目中的 Log 管理系统,其实只是将系统原生 Log 进行输出并导出,并没有太复杂的操作。还有一种 Log 管理系统需要对 Android 原生 Log 系统进行重写,例如我们使用 Log.d(tag, msg) 打印 Log,需要我们根据 tag 信息将不同模块的 Log 数据写入不同的本地文件下,这样可以方便不同模块查看自己的 Log,追踪异常问题。

小旭的专栏 3772

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java AIO详解

AIO(异步I/O)是Java的一种高级I/O模型,通过完全异步的方式允许线程发起I/O请求后立即返回,大大提升了性能和效率。相较于NIO和BIO,AIO采用了回调机制来处理I/O操作结果,适用于高并发的网络应用场景。在JDK 1.7及以上版本中引入的NIO2部分增加了多种异步通道,支持Windows和Linux两大操作系统的异步I/O实现。

叉烧钵钵鸡的博客 1160

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java AIO知识总结

文章目录概述什么是AIO?AIO与NIO有什么区别?AIO性能比NIO更好吗?什么是epoll?AIO既然是异步的,那么如何获得操作结果?Java AIO的API使用了解CompletionHandler接口CompletionHandler源码解析completedfailedDemo基于AIO的简单时间服务Server端实现代码Client端实现代码 概述 什么是AIO? Java 1.7升级...

I'm Baymax D 1535

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Java AIO - 异步IO详解

本文主要对异步IO和Java中对AIO的支持详解。

珍惜当下 886

java aio事件模型_JAVA AIO

JDK7中新增了一些与文件(网络)I/O相关的一些API,这些API被称为NIO2,或称为AIO(Asynchronous I/O)。全部章节传送门:AIO 介绍AIO最大的一个特性就是异步能力,这种能力对socket与文件I/O都起作用。AIO其实是一种在读写操作结束之前允许进行其他操作的I/O处理。AIO是对JDK1.4中提出的同步非阻塞I/O(NIO)的进一步增强。增加的新的类如下:Asyn...

weixin_34757654的博客 251

java aio_【Java】Java AIO使用

欢迎关注公众号: nullobject 。文章首发在个人博客 https://www.nullobject.cn,公众号nullobject同步更新。这篇文章主要介绍Java AIO网络编程。1. AIO是什么本文所说的AIO特指Java环境下的AIO。AIO是java中IO模型的一种,作为NIO的改进和增强随JDK1.7版本更新被集成在JDK的nio包中,因此AIO也被称作是NIO2.0。区别于...

weixin_32973973的博客 487

Java AIO使用详解

1. AIO是什么 本文所说的AIO特指Java环境下的AIO。AIO是java中IO模型的一种,作为NIO的改进和增强随JDK1.7版本更新被集成在JDK的nio包中,因此AIO也被称作是NIO2.0。区别于传统的BIO(Blocking IO,同步阻塞式模型,JDK1.4之前就存在于JDK中,NIO于JDK1.4版本发布更新)的阻塞式读写,AIO提供了从建立连接到读、写的全异步操作。AIO可用于异步的文件读写和网络通信。本文将介绍如何使用AIO实现一个简单的网络通信以及AIO的一些比较关键的API。

hw1197328718的博客 6226

JAVA AIO编程

概述 什么是AIO? Java 1.7升级了NIO类库,升级后的NIO类库被称为NIO 2.0,在NIO2.0中Java提供了异步文件I/O操作,同时提供了与UNIX网络编程事件驱动I/O对应的AIO(Asynchronous I/O),AIO是真正的异步非阻塞I/O,它不需要通过多路复用器(Selector)对注册的通道进行轮询操作即可实现异步读写,从而简化了NIO的编程模型。 AIO与NIO有...

weixin_44117767的博客 340

Java-AIO

Asynchronous IO也称为AIO,即异步⾮阻塞IO。Java7提供了改进版的NIO,引⼊了异步⾮阻塞的IO,由操作系统完成后回调通知服务端程序启动线程去处理。⼀般适⽤于连接数较多且连接时间较⻓的应⽤。

z2698751935的博客 845

JAVA的BIO,NIO,AIO

一:名词解释 NIO nio 是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持锁和内存映射文件的文件访问接口。 – 提供多路 (non-bloking) 非阻塞式的高伸缩性网络 I

janvinal的专栏 1106

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需要操作系统支持、并发也同样需要操作系统的支持,所以性能方面不同操作系统差异会比较明显。所以本文也附带...

weixin_34625578的博客 471
上一篇: java io以及unix io模型
下一篇: JAVA NIO 之Channel
jamespengo
博客等级 码龄16年 83粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值