一、AIO介绍
JDK 7 引入了 Asynchronous I/O,即 AIO。在进行 I/O 编程中,常用到两种模式: Reactor 和 Proactor。Java 的 NIO 就是 Reactor——当有事件触发时,服务器端得到通知,进行相应的处理。
AIO 即 NIO2.0,叫做异步不阻塞的 IO。AIO 引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用。目前 AIO 还没有广泛应用,Netty 也是基于 NIO, 而不是 AIO。
在 AIO 的实施过程中,IO需要操作系统支持、并发也需要操作系统的支持,所以 AIO 在性能方面不同操作系统差异会比较明显。
和多路复用的 java nio 相比较,异步非阻塞 io 是在数据读取或者写入调用已经完成的时候,再通知调用者,而非阻塞多路复用 io (即NIO)则是在有数据就绪,可以读写的时候通知调用者,读写仍然是由调用者执行并且读写是阻塞的,这意味着如果要同时进行其他工作,则要控制读写操作不能阻塞太长时间或者需要将其放去单独的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来设定回调操作
AIO 背后的基本思想是允许进程发起很多 I/O 操作,而不用阻塞或等待任何操作完成。稍后或在接收到 I/O 操作完成的通知时,进程就可以检索 I/O 操作的结果,它的异步是基于事件回调的,和NIO不同的是,NIO 在channel注册到Selector时虽然也指定了关注的事件,但需要用户线程自己去轮询是否有自己关注的事件发生(其实是轮询读或写是否准备好),AIO则是由操作系统完成回调,而这也正是同步和异步的区别。
NIO 的同步非阻塞模型:
AIO 的异步非阻塞模型:读操作会立即返回,待读操作真正完成后会回调事件通知线程处理
二、BIO、NIO和AIO的对比
BIO | NIO | AIO | |
---|---|---|---|
IO模型 | 同步阻塞 | 同步非阻塞 | 异步非阻塞 |
编程难度 | 简单 | 复杂 | 复杂 |
可靠性 | 差 | 好 | 好 |
吞吐量 | 低 | 高 | 高 |