Guide to Java NIO2 Asynchronous Channel APIs – Java NIO2异步通道API指南

最后修改: 2016年 12月 1日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we are going to explore the foundations of one of the key additional APIs of the new I/O (NIO2) in Java 7- asynchronous channel APIs.

在这篇文章中,我们将探讨Java 7中新I/O(NIO2)的一个关键附加API的基础–异步通道API

This is first in a series of articles that will cover this particular topic.

这是涉及这一特定主题的系列文章中的第一篇。

The asynchronous channel APIs are an enhancement to the earlier new I/O (NIO) APIs that shipped with Java 1.4. To read about NIO Selectors, please follow this link.

异步通道 API 是对早期随 Java 1.4 出厂的新 I/O (NIO) API 的增强。要阅读有关NIO选择器的内容,请遵循这个链接

Another enhancement to the NIO APIs is the new File System API. You can read more about its file operations and path operations on this site too.

NIO API的另一项改进是新的文件系统API。你也可以在这个网站上阅读关于其文件操作路径操作的更多信息。

To use the NIO2 asynchronous channels in our projects, we have to import the java.nio.channels package as the required classes are bundled in it:

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

import java.nio.channels.*;

2. How Asynchronous Channel APIs Work

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

The asynchronous channel APIs were introduced into the existing java.nio.channels package, simply put – by prefixing the class names with the word Asynchronous.

异步通道API被引入到现有的java.nio.channels包中,简单地说,就是在类名前加上Asynchronous

Some of the core classes include: AsynchronousSocketChannel, AsynchronousServerSocketChannel and AsynchronousFileChannel.

一些核心类包括。AsynchronousSocketChannel, AsynchronousServerSocketChannelAsynchronousFileChannel

As you may have noticed, these classes are similar in style to the standard NIO channel APIs.

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

And, most API operations available to the NIO channel classes are also available in the new asynchronous versions. The main difference is that the new channels enable some operations to be executed asynchronously.

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

When an operation is initiated, the asynchronous channel APIs provide us with two alternatives for monitoring and controlling the pending operations. The operation can return java.util.concurrent.Future object or we can pass to it a java.nio.channels.CompletionHandler.

当一个操作被启动时,异步通道API为我们提供了两种选择,用于监视和控制未决的操作。操作可以返回java.util.concurrent.Future对象,或者我们可以给它传递一个java.nio.channels.CompletionHandler

3. The Future Approach

3、未来的方法

A Future object represents a result of an asynchronous computation. Assuming we want to create a server to listen to client connections, we call the static open API on the AsynchronousServerSocketChannel and optionally bind the returned socket channel to an address:

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

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

We have passed in null so that the system can auto-assign an address. Then, we call the accept method on the returned server SocketChannel:

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

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

When we call the accept method of a ServerSocketChannel in the old IO, it blocks until an incoming connection is received from a client. But the accept method of an AsynchronousServerSocketChannel returns a Future object right away.

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

The generic type of the Future object is the return type of the operation. In our case above, it is AsynchronousSocketChannel but it could just as well have been Integer or String, depending on the ultimate return type of the operation.

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

We can use the Future object to query the state of the operation:

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

future.isDone();

This API returns true if the underlying operation already completed. Note that completion, in this case, may mean normal termination, an exception, or cancellation.

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

We can also explicitly check if the operation has been canceled:

我们还可以明确地检查操作是否被取消。

future.isCancelled();

It only returns true if the operation was canceled before completing normally, otherwise, it returns false. Cancellation is performed by the cancel method:

它只在操作正常完成前被取消时返回true,否则,它返回false。取消操作是由cancel方法执行的。

future.cancel(true);

The call cancels the operation represented by the Future object. The parameter indicates that even if the operation has started, it can be interrupted. Once an operation has completed, it cannot be canceled

该调用取消了由Future对象代表的操作。该参数表明,即使操作已经开始,它也可以被中断。一旦一个操作完成,它就不能被取消

To retrieve the result of a computation, we use the get method:

为了检索一个计算的结果,我们使用get方法。

AsynchronousSocketChannel client= future.get();

If we call this API before the operation completes, it will block until completion and then return the result of the operation.

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

4. The CompletionHandler Approach

4.CompletionHandler方法

The alternative to using Future to handle operations is a callback mechanism using the CompletionHandler class. The asynchronous channels allow a completion handler to be specified to consume the result of an operation:

使用Future来处理操作的替代方法是使用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
      }
  });

The completed callback API is invoked when the I/O operation completes successfully. The failed callback is invoked if the operation has failed.

当I/O操作成功完成时,completedcallback API被调用。如果操作失败,failed回调会被调用。

These callback methods accept other parameters – to allow us to pass in any data we think may be suitable to tag along with the operation. This first parameter is available as the second parameter of the callback method.

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

Finally, a clear scenario is – using the same CompletionHandler for different asynchronous operations. In this case, we’d benefit from tagging each operation to provide context when handling the results we will see this in action in the following section.

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

5. Conclusion

5.结论

In this article, we have explored introductory aspects of the Asynchronous Channel APIs of Java NIO2.

在这篇文章中,我们已经探讨了Java NIO2的异步通道API的介绍性内容。

To get all code snippets and the full source code for this article, you can visit the GitHub project.

要获得本文的所有代码片段和完整的源代码,你可以访问GitHub项目