AIO(异步非阻塞)AIO采用了Proactor模式,AIO与NIO的不同之处在于当AIO在进行读写操作时,不用先等通知,可直接调用相应的read/write方法,这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序,而NIO的通知是发生在动作之前的,是在可读、写的时候,Selector发现了这些事件后调用Handler处理.

在AIO socket编程中,服务端通道是AsynchronousServerSocketChannel,这个类提供了一个open()静态工厂,一个bind()方法用于绑定服务端IP地址(还有端口号),另外还提供了accept()用于接收用户连接请求。在客户端使用的通道是AsynchronousSocketChannel,这个通道处理提供open静态工厂方法外,还提供了read和write方法。

在AIO编程中,发出一个事件(accept read write等)之后要指定事件处理类(回调函数),AIO中的事件处理类是CompletionHandler<V,A>,这个接口定义了如下两个方法,分别在异步操作成功和失败时被回调。

void completed(V result, A attachment);

void failed(Throwable exc, A attachment);

  1. import java.io.IOException;
  2. import java.net.InetSocketAddress;
  3. import java.nio.ByteBuffer;
  4. import java.nio.channels.AsynchronousServerSocketChannel;
  5. import java.nio.channels.AsynchronousSocketChannel;
  6. import java.nio.channels.CompletionHandler;
  7. import java.util.concurrent.ExecutionException;
  8. import java.util.concurrent.Future;
  9. import java.util.concurrent.TimeUnit;
  10. import java.util.concurrent.TimeoutException;
  11. public class AIOEchoServer {
  12. public final static int PORT = 8001;
  13. public final static String IP = "127.0.0.1";
  14. private AsynchronousServerSocketChannel server = null;
  15. public AIOEchoServer(){
  16. try {
  17. //同样是利用工厂方法产生一个通道,异步通道 AsynchronousServerSocketChannel
  18. server = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(IP,PORT));
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. //使用这个通道(server)来进行客户端的接收和处理
  24. public void start(){
  25. System.out.println("Server listen on "+PORT);
  26. //注册事件和事件完成后的处理器,这个CompletionHandler就是事件完成后的处理器
  27. server.accept(null,new CompletionHandler<AsynchronousSocketChannel,Object>(){
  28. final ByteBuffer buffer = ByteBuffer.allocate(1024);
  29. @Override
  30. public void completed(AsynchronousSocketChannel result,Object attachment) {
  31. System.out.println(Thread.currentThread().getName());
  32. Future<Integer> writeResult = null;
  33. try{
  34. buffer.clear();
  35. result.read(buffer).get(100,TimeUnit.SECONDS);
  36. System.out.println("In server: "+ new String(buffer.array()));
  37. //将数据写回客户端
  38. buffer.flip();
  39. writeResult = result.write(buffer);
  40. }catch(InterruptedException | ExecutionException | TimeoutException e){
  41. e.printStackTrace();
  42. }finally{
  43. server.accept(null,this);
  44. try {
  45. writeResult.get();
  46. result.close();
  47. } catch (InterruptedException | ExecutionException e) {
  48. e.printStackTrace();
  49. } catch (IOException e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. }
  54. @Override
  55. public void failed(Throwable exc, Object attachment) {
  56. System.out.println("failed:"+exc);
  57. }
  58. });
  59. }
  60. public static void main(String[] args) {
  61. new AIOEchoServer().start();
  62. while(true){
  63. try {
  64. Thread.sleep(1000);
  65. } catch (InterruptedException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70. }

客户端:

    1. import java.io.IOException;
    2. import java.net.InetSocketAddress;
    3. import java.nio.ByteBuffer;
    4. import java.nio.channels.AsynchronousSocketChannel;
    5. import java.nio.channels.CompletionHandler;
    6. public class AIOClient {
    7. public static void main(String[] args) throws IOException {
    8. final AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
    9. InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1",8001);
    10. CompletionHandler<Void, ? super Object> handler = new CompletionHandler<Void,Object>(){
    11. @Override
    12. public void completed(Void result, Object attachment) {
    13. client.write(ByteBuffer.wrap("Hello".getBytes()),null,
    14. new CompletionHandler<Integer,Object>(){
    15. @Override
    16. public void completed(Integer result,
    17. Object attachment) {
    18. final ByteBuffer buffer = ByteBuffer.allocate(1024);
    19. client.read(buffer,buffer,new CompletionHandler<Integer,ByteBuffer>(){
    20. @Override
    21. public void completed(Integer result,
    22. ByteBuffer attachment) {
    23. buffer.flip();
    24. System.out.println(new String(buffer.array()));
    25. try {
    26. client.close();
    27. } catch (IOException e) {
    28. e.printStackTrace();
    29. }
    30. }
    31. @Override
    32. public void failed(Throwable exc,
    33. ByteBuffer attachment) {
    34. }
    35. });
    36. }
    37. @Override
    38. public void failed(Throwable exc, Object attachment) {
    39. }
    40. });
    41. }
    42. @Override
    43. public void failed(Throwable exc, Object attachment) {
    44. }
    45. };
    46. client.connect(serverAddress, null, handler);
    47. try {
    48. Thread.sleep(1000);
    49. } catch (InterruptedException e) {
    50. e.printStackTrace();
    51. }
    52. }
    53. }

java中的AIO的更多相关文章

  1. 再谈一次关于Java中的 AIO(异步IO) 与 NIO(非阻塞IO)

    今天用ab进行压力测试时,无意发现的: Requests per second:    xxx [#/sec] (mean) ab -n 5000 -c 1000 http://www:8080/up ...

  2. Java中的IO、NIO、File、BIO、AIO详解

    java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?         Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包 ...

  3. 深入理解Java AIO(三)—— Linux中的AIO实现

    我们调用的Java AIO底层也是要调用OS的AIO实现,而OS主要也就Windows和Linux这两大类,当然还有Solaris和mac这些小众的. 在 Windows 操作系统中,提供了一个叫做 ...

  4. 京东数科二面:常见的 IO 模型有哪些?Java 中的 BIO、NIO、AIO 有啥区别?

    IO 模型这块确实挺难理解的,需要太多计算机底层知识.写这篇文章用了挺久,就非常希望能把我所知道的讲出来吧!希望朋友们能有收货!为了写这篇文章,还翻看了一下<UNIX 网络编程>这本书,太 ...

  5. 京东数科面试真题:常见的 IO 模型有哪些?Java 中的 BIO、NIO、AIO 有啥区别?

    本文节选自<Java面试进阶指北 打造个人的技术竞争力> 面试中经常喜欢问的一个问题,因为通过这个问题,面试官可以顺便了解一下你的操作系统的水平. IO 模型这块确实挺难理解的,需要太多计 ...

  6. Java 中的纤程库 – Quasar

    来源:鸟窝, colobu.com/2016/07/14/Java-Fiber-Quasar/ 如有好文章投稿,请点击 → 这里了解详情 最近遇到的一个问题大概是微服务架构中经常会遇到的一个问题: 服 ...

  7. 【笔试题】Java 中如何递归显示一个目录下面的所有目录和文件?

    笔试题 Java 中如何递归显示一个目录下面的所有目录和文件? import java.io.File; public class Test { private static void showDir ...

  8. Java NIO学习系列六:Java中的IO模型

    前文中我们总结了linux系统中的5中IO模型,并且着重介绍了其中的4种IO模型: 阻塞I/O(blocking IO) 非阻塞I/O(nonblocking IO) I/O多路复用(IO multi ...

  9. Java NIO之Java中的IO分类

    前言 前面两篇文章(Java NIO之理解I/O模型(一).Java NIO之理解I/O模型(二))介绍了,IO的机制,以及几种IO模型的内容,还有涉及到的设计模式.这次要写一些更贴近实际一些的内容了 ...

随机推荐

  1. 配置jdbc问题 mysql与IDEA

    1.新建lib文件夹,将jar文件导入 2在structure中添加jar文件 3设置url时需要设置时区: import java.sql.Connection;import java.sql.Dr ...

  2. dotnet core use MangoDB

    安装MangoDB 同样我这边再次使用Docker, 方便快捷: # 拉取镜像 docker pull mongo # 运行镜像 docker run -d -p 37017:27017 --name ...

  3. [Nuget] - "Runtime error: Could not load file or assembly 'System.Web.WebPages.Razor, Version=3.0.0.0'" 问题之解决

    环境 项目中使用了 System.Web.WebPages.Razor, Version=3.0.0.0,Nuget 还原缺失包后自动更新至 Version=3.2.5.0,编译成功,运行失败. 错误 ...

  4. Scratch(三)剪刀石头布

    经过上一讲的突击训练,我们从门外汉开始走向编程的深坑,我们今天还要对上一讲的游戏进行加强. 上一个游戏还能演变成什么游戏呢? 我其实知道你们想到的是老hu机什么的,确实,上一个游戏改改可以变成老hu机 ...

  5. 简单添加自己的驱动程序到Linux内核树中

    背景: 移植4g模块的时候,看到文档中有添加驱动到内核的步骤,于是趁着这个机会,展开有关的学习. 了解更多可以访问:<Kconfig语法简介> Target :hi3531d Linux ...

  6. 撸一个 vue 的截图组件,按比例截取

    <template> <div class="clip-img" :style="imgStyle"> <img :src=&qu ...

  7. Singer House CodeForces - 830D (组合计数,dp)

    大意: 一个$k$层完全二叉树, 每个节点向它祖先连边, 就得到一个$k$房子, 求$k$房子的所有简单路径数. $DP$好题. 首先设$dp_{i,j}$表示$i$房子, 分出$j$条简单路径的方案 ...

  8. DO、VO、DTO 区别

    DTO:数据传输对象,主要用于外部接口参数传递封装,接口与接口进行传递使用. VO:视图对象,主要用于给前端返回页面参数使用. DO:数据对象,主要用于数据库层传递. DTO转DO:接口接收参数将参数 ...

  9. wget的url获取方式

    获取方式 每次用wget都是在网上查相应的url,但以前没怎么关注过这个url是怎么获取到的,这里总结一下 这里以下载jekins为例: 打开jekins网站:https://jenkins.io/d ...

  10. 【MySQL】数据库(分库分表)中间件对比

    分区:对业务透明,分区只不过把存放数据的文件分成了许多小块,例如mysql中的一张表对应三个文件.MYD,MYI,frm. 根据一定的规则把数据文件(MYD)和索引文件(MYI)进行了分割,分区后的表 ...