(1)概念原理
AIO自JDK1.7以后才开始支持,是异步非阻塞的,与NIO不同,当进行读写操作时,只需直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。即可以理解为, read/write方法都是异步的,完成后会主动调用回调函数。
AIO基于Proactor模型实现,分为发送请求和读取数据两个步骤:
发送请求:将数据写入的缓冲区后,剩下的交给操作系统去完成
读取数据:操作系统写回数据也是写到Buffer里面,完成后再通知客户端来进行读取数据。
AIO主要在java.nio.channels包下增加了下面四个异步通道
AsynchronousSocketChannel
AsynchronousServerSocketChannel
AsynchronousFileChannel
AsynchronousDatagramChannel
其中的read/write方法,会返回一个带回调函数的对象,当执行完读取/写入操作后,直接调用回调函数。?
为什么大多数公司并没有使用AIO,而是使用了netty?
AIO的底层实现仍使用Epoll,并没有很好的实现异步,在性能上对比NIO没有太大优势
AIO的代码逻辑比较复杂,且Linux上AIO还不够成熟
Netty在NIO上做了很多异步的封装,是异步非阻塞框架
(2)AIOServer
public class AIOServer {
? ? public static void main(String[] args) throws IOException, InterruptedException {
? ? ? ? AsynchronousServerSocketChannel ssc = AsynchronousServerSocketChannel.open();
? ? ? ? ssc.bind(new InetSocketAddress(9001));
? ? ? ? ssc.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ssc.accept(attachment, this);
? ? ? ? ? ? ? ? ? ? System.out.println(socketChannel.getRemoteAddress());
? ? ? ? ? ? ? ? ? ? ByteBuffer buffer = ByteBuffer.allocate(1024);
? ? ? ? ? ? ? ? ? ? socketChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? public void completed(Integer result, ByteBuffer bf) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? bf.flip();
? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(new String(bf.array(), 0, result));
? ? ? ? ? ? ? ? ? ? ? ? ? ? ByteBuffer send = ByteBuffer.wrap("Hello Client".getBytes());
? ? ? ? ? ? ? ? ? ? ? ? ? ? socketChannel.write(send);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? public void failed(Throwable exc, ByteBuffer attachment) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? exc.printStackTrace();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? } catch (Exception ex) {
? ? ? ? ? ? ? ? ? ? ex.printStackTrace();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public void failed(Throwable exc, Object attachment) {
? ? ? ? ? ? ? ? exc.printStackTrace();
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? Thread.sleep(Integer.MAX_VALUE);
? ? }
}
(3)AIOClient
public class AIOClient {
? ? public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
? ? ? ? AsynchronousSocketChannel sc = AsynchronousSocketChannel.open();
? ? ? ? sc.connect(new InetSocketAddress("127.0.0.1", 9001)).get();
? ? ? ? sc.write(ByteBuffer.wrap("Hello Server".getBytes()));
? ? ? ? ByteBuffer bf = ByteBuffer.allocate(0124);
? ? ? ? Integer len = sc.read(bf).get();
? ? ? ? if (len != -1) {
? ? ? ? ? ? System.out.println("收到服务端数据: "+new String(bf.array(), 0, len));
? ? ? ? }
? ? }
}