java AIO的一些基本概念

主要对象

AsynchronousChannelGroup

异步channel的分组管理,目的是为了资源共享。一个AsynchronousChannelGroup绑定一个线程池,这个线程池执行两个任务:处理IO事件和派发CompletionHandler。AsynchronousServerSocketChannel创建的时候可以传入一个AsynchronousChannelGroup,那么通过AsynchronousServerSocketChannel创建的AsynchronousSocketChannel将同属于一个组,共享资源。
AsynchronousChannelGroup允许绑定不同的线程池,通过三个静态方法来创建:

public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,
                                                              ThreadFactory threadFactory)
       throws IOException

public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,
                                                               int initialSize)

public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)
        throws IOException

AsynchronousServerSocketChannel

ServerSocket的aio版本,创建TCP服务端,绑定地址,监听端口等。

AsynchronousSocketChannel

面向流的异步socket channel,表示一个连接。

CompletionHandler

异步IO操作结果的回调接口,用于定义在IO操作完成后所作的回调工作。AIO的API允许两种方式来处理异步操作的结果:返回的Future模式或者注册CompletionHandler,推荐用CompletionHandler的方式,这些handler的调用是由AsynchronousChannelGroup的线程池派发的。显然,线程池的大小是性能的关键因素。
CompletionHandler有三个方法,分别对应于处理成功、失败、被取消(通过返回的Future)情况下的回调处理:

public interface CompletionHandler<V,A> {

    void completed(V result, A attachment);

    void failed(Throwable exc, A attachment);

    void cancelled(A attachment);
}

代码示例

下面就是通过AsynchronousServerSocketChannel实现的一个简单的EchoServer,服务器会打印出收到的客户端输入,并把输入写回客户端。(注:代码只有在JDK1.7下才能编译通过)

public class AIOEchoServer {
  private AsynchronousServerSocketChannel server;

  public static void main(String[] args) throws IOException {
    AIOEchoServer aioServer = new AIOEchoServer();
    aioServer.init("localhost", 6025);
  }

  private void init(String host, int port) throws IOException {
    //ChannelGroup用来管理共享资源
    AsynchronousChannelGroup group = AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10);
    server = AsynchronousServerSocketChannel.open(group);
    //通过setOption配置Socket
    server.setOption(StandardSocketOptions.SO_REUSEADDR, true);
    server.setOption(StandardSocketOptions.SO_RCVBUF, 16 * 1024);
    //绑定到指定的主机,端口
    server.bind(new InetSocketAddress(host, port));
    System.out.println("Listening on " + host + ":" + port);
    //输出provider
    System.out.println("Channel Provider : " + server.provider());
    //等待连接,并注册CompletionHandler处理内核完成后的操作。
    server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
      final ByteBuffer buffer = ByteBuffer.allocate(1024);

      @Override
      public void completed(AsynchronousSocketChannel result, Object attachment) {
        System.out.println("waiting....");
        buffer.clear();
        try {
          //把socket中的数据读取到buffer中
          result.read(buffer).get();
          buffer.flip();
          System.out.println("Echo " + new String(buffer.array()).trim() + " to " + result);

          //把收到的直接返回给客户端
          result.write(buffer);
          buffer.flip();
        } catch (InterruptedException e) {
          e.printStackTrace();
        } catch (ExecutionException e) {
          e.printStackTrace();
        } finally {
          try {
            //关闭处理完的socket,并重新调用accept等待新的连接
            result.close();
            server.accept(null, this);
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }

      @Override
      public void failed(Throwable exc, Object attachment) {
        System.out.print("Server failed...." + exc.getCause());
        server.accept(null, this);
      }
    });

    //因为AIO不会阻塞调用进程,因此必须在主进程阻塞,才能保持进程存活。
    try {
      Thread.sleep(Integer.MAX_VALUE);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

Future对象的说明

概念

Future对象的get()方法会阻塞该线程,所以这种方式是阻塞式的异步IO。

示例

while (true) {
  Future<AsynchronousSocketChannel> future = serverSocketChannel.accept();
  AsynchronousSocketChannel socketChannel = null;
  try {
    socketChannel = future.get();
    socketChannel.write(ByteBuffer.wrap("ssss".getBytes("UTF-8")));
  } catch (Exception e) {
    e.printStackTrace();
  }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值