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. xadmin自定义菜单、增加功能、富文本编辑器

    xadmin功能:https://www.cnblogs.com/derek1184405959/p/8682250.html#blogTitle7

  2. js里typeof和instanceof和箭头表达式要注意的地方,以及其他

    如果学过类似C#这样的语言,然后定义两个类class Mu{}和class Ku{},那么显然typeof Mu != typeof Ku的,但是在js里则不是这样,对于Mu和Ku的对象进行typeo ...

  3. Linux查看库依赖方法

    1.查看依赖的库:objdump -x xxx.so | grep NEEDED 2.查看可执行程序依赖的库:objdump -x 可执行程序名 | grep NEEDED 3.查看缺少的库: ldd ...

  4. Java线程同步synchronized的理解

    JVM中(留神:马上讲到的这两个存储区只在JVM内部与物理存储区无关)存在一个主内存(Main Memory),Java中所有的变量存储在主内存中,所有实例和实例的字段都在此区域,对于所有的线程是共享 ...

  5. Java基础笔试练习(四)

    1.编译Java Application 源程序文件将产生相应的字节码文件,这些字节码文件的扩展名为( ). A.java B.class C.html D.exe 答案: B 解析: Java源程序 ...

  6. python 之 前端开发(form标签、单选框、多选框、file上传文件、按钮、label标签、下拉列表、textarea标签、fieldset标签、table标签)

    11.25 form标签 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  7. docker 实践十一:docker 跨主机通讯

    在上一篇了解了关于 docker 的网络模型后,本篇就基于上一篇的基础来实现 docker 的跨主机通信. 注:环境为 CentOS7,docker 19.03. 本篇会尝试使用几种不同的方式来实现跨 ...

  8. 利用strace & Perf分析MySQL

    strace介绍及用途 strace是一个用于诊断,分析linux用户态进程的工具 类似的工具pstrace,lsof,gdb,pstrack strace观察mysqld对my.cnf 配置文件的加 ...

  9. NOP法破解

    目录 步骤 步骤 OD载入目标软件,汇编窗口右键搜索字符串,发现错误类提示字符串,双击该字符串来到该段代码位置. 向上寻找到跳转到本段错误提示代码的跳转指令,用NOP指令填充跳转指令. 保存修改后的代 ...

  10. Linux or Mac 重启网络

    Mac sudo ifconfig en0 down sudo ifconfig en0 up Linux /etc/init.d/networking restart