Java NIO 2 AsynchronousChannel API指南

2023/05/29

1. 概述

在本文中,我们将探讨Java 7中新I/O(NIO2)的关键附加API之一的基础-异步通道API

这是涵盖该特定主题的一系列文章中的第一篇。

异步通道API是对Java 1.4附带的早期新I/O(NIO) API的增强。要了解NIO Selector,请点击此链接

NIO API的另一个增强是新的文件系统API。你也可以在此站点上阅读有关其文件操作路径操作的更多信息。

要在我们的项目中使用NIO2异步通道,我们必须导入java.nio.channels包,因为其中捆绑了所需的类:

import java.nio.channels.*;

2. 异步通道API的工作原理

异步通道API被引入到现有的java.nio.channels包中,简单地说-通过在类名前加上Asynchronous一词作为前缀。

一些核心类包括:AsynchronousSocketChannel、AsynchronousServerSocketChannel和AsynchronousFileChannel。

你可能已经注意到,这些类在风格上与标准NIO通道API相似。

而且,大多数可用于NIO通道类的API操作在新的异步版本中也可用。主要区别在于新通道使某些操作能够异步执行

启动操作时,异步通道API为我们提供了两种监视和控制挂起操作的替代方法。该操作可以返回java.util.concurrent.Future对象,或者我们可以将java.nio.channels.CompletionHandler传递给它。

3. Future方法

Future对象表示异步计算的结果。假设我们要创建一个服务器来监听客户端连接,我们调用AsynchronousServerSocketChannel上的静态open API,并可选择将返回的套接字通道绑定到一个地址:

AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open().bind(null);

我们传入了null以便系统可以自动分配地址。然后,我们在返回的服务器SocketChannel上调用accept方法:

Future<AsynchronousSocketChannel> future = server.accept();

当我们在旧IO中调用ServerSocketChannel的accept方法时,它会阻塞,直到从客户端接收到传入连接。但是AsynchronousServerSocketChannel的accept方法会立即返回一个Future对象。

Future对象的泛型类型是操作的返回类型。在我们上面的例子中,它是AsynchronousSocketChannel,但它也可以是Integer或String,这取决于操作的最终返回类型。

我们可以使用Future对象来查询操作的状态:

future.isDone();

如果底层操作已经完成,则此API返回true。请注意,在这种情况下,完成可能意味着正常终止、异常或取消。

我们还可以显式检查操作是否已被取消:

future.isCancelled();

仅当操作在正常完成之前被取消时才返回true,否则返回false。通过cancel方法执行取消:

future.cancel(true);

该调用取消了Future对象表示的操作。该参数表示即使操作已经开始,也可以中断。操作完成后无法取消。

要检索计算结果,我们使用get方法:

AsynchronousSocketChannel client= future.get();

如果我们在操作完成之前调用此API,它将阻塞直到完成,然后返回操作的结果。

4. CompletionHandler方法

使用Future处理操作的替代方法是使用CompletionHandler类的回调机制。异步通道允许指定CompletionHandler来使用操作的结果:

AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel.open().bind(null);

listener.accept(attachment, new CompletionHandler<AsynchronousSocketChannel, Object>() {
    public void completed(AsynchronousSocketChannel client, Object attachment) {
        // do whatever with client
    }
    
    public void failed(Throwable exc, Object attachment) {
        // handle failure
    }
});

当I/O操作成功完成时,将调用completed回调API。如果操作失败,则调用failed回调。

这些回调方法接收其他参数-允许我们传入我们认为可能适合与操作一起标记的任何数据。第一个参数可用作回调方法的第二个参数。

最后,一个明确的场景是-对不同的异步操作使用相同的CompletionHandler。在这种情况下,我们将受益于标记每个操作以在处理结果时提供上下文,我们将在下一节中看到这一点。

5. 总结

在本文中,我们探讨了Java NIO2的异步通道API的介绍性方面。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章