Guia para APIs de canal assíncrono Java NIO2

Guia para APIs de canal assíncrono Java NIO2

1. Visão geral

Neste artigo, vamos explorar os fundamentos de uma das principais APIs adicionais do novo I / O (NIO2) em Java 7-asynchronous channel APIs.

Este é o primeiro de uma série de artigos que abordarão esse tópico específico.

As APIs de canal assíncrono são um aprimoramento para as novas APIs de E / S (NIO) anteriores, fornecidas com o Java 1.4. Para ler sobre os seletores NIO, sigathis link.

Outro aprimoramento para as APIs NIO é a nova API do sistema de arquivos. Você pode ler mais sobre seusfile operationsepath operations neste site também.

Para usar os canais assíncronos NIO2 em nossos projetos, temos que importar o pacotejava.nio.channels, pois as classes necessárias estão agrupadas nele:

import java.nio.channels.*;

2. Como funcionam as APIs de canal assíncrono

As APIs de canal assíncrono foram introduzidas no pacotejava.nio.channels existente, simplesmente colocado - prefixando os nomes das classes com a palavraAsynchronous.

Algumas das classes principais incluem:AsynchronousSocketChannel,AsynchronousServerSocketChanneleAsynchronousFileChannel.

Como você deve ter notado, essas classes têm estilo semelhante às APIs de canal NIO padrão.

E a maioria das operações de API disponíveis para as classes de canal NIO também estão disponíveis nas novas versões assíncronas. A principal diferença é quethe new channels enable some operations to be executed asynchronously.

Quando uma operação é iniciada, as APIs do canal assíncrono nos fornecem duas alternativas para monitorar e controlar as operações pendentes. A operação pode retornar o objetojava.util.concurrent.Future ou podemos passar para ela umjava.nio.channels.CompletionHandler.

3. A abordagemFuture

A Future object represents a result of an asynchronous computation. Supondo que queremos criar um servidor para ouvir as conexões do cliente, chamamos a APIopen estática noAsynchronousServerSocketChannel e opcionalmente vinculamos o canal de soquete retornado a um endereço:

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

Passamosnull para que o sistema possa atribuir um endereço automaticamente. Então, chamamos o métodoaccept no servidor retornadoSocketChannel:

Future future = server.accept();

Quando chamamos o métodoaccept de aServerSocketChannel no IO antigo, ele bloqueia até que uma conexão de entrada seja recebida de um cliente. Mas o métodoaccept de umAsynchronousServerSocketChannel retorna um objetoFuture imediatamente.

O tipo genérico do objetoFuture é o tipo de retorno da operação. Em nosso caso acima, éAsynchronousSocketChannel, mas também poderia serInteger ouString, dependendo do tipo de retorno final da operação.

Podemos usar o objetoFuture para consultar o estado da operação:

future.isDone();

Esta API retornatrue se a operação subjacente já foi concluída. Observe que a conclusão, nesse caso, pode significar rescisão normal, uma exceção ou cancelamento.

Também podemos verificar explicitamente se a operação foi cancelada:

future.isCancelled();

Ele só retornatrue se a operação foi cancelada antes de ser concluída normalmente, caso contrário, retornafalse. O cancelamento é realizado pelo métodocancel:

future.cancel(true);

A chamada cancela a operação representada pelo objetoFuture. O parâmetro indica que, mesmo que a operação tenha sido iniciada, ela pode ser interrompida. Depois que uma operação é concluída, ela não pode ser cancelada

Para recuperar o resultado de um cálculo, usamos o métodoget:

AsynchronousSocketChannel client= future.get();

Se chamarmos essa API antes que a operação seja concluída, ela bloqueará até a conclusão e retornará o resultado da operação.

4. A abordagemCompletionHandler

A alternativa de usar Future para manipular operações é um mecanismo de retorno de chamada usando a classeCompletionHandler. Os canais assíncronos permitem que um manipulador de conclusão seja especificado para consumir o resultado de uma operação:

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

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

A API de retorno de chamadacompleted é chamada quando a operação de E / S é concluída com êxito. O retorno de chamadafailed é invocado se a operação falhar.

Esses métodos de retorno de chamada aceitam outros parâmetros - para permitir a transmissão de qualquer dado que julgarmos adequado para marcar junto com a operação. Este primeiro parâmetro está disponível como o segundo parâmetro do método de retorno de chamada.

Finalmente, um cenário claro é - usando o mesmoCompletionHandler para diferentes operações assíncronas. Nesse caso, nos beneficiaríamos com a marcação de cada operação para fornecer contexto ao lidar com os resultados, veremos isso em ação na seção a seguir.

5. Conclusão

Neste artigo, exploramos aspectos introdutórios das APIs de canal assíncrono do Java NIO2.

Para obter todos os trechos de código e o código-fonte completo para este artigo, você pode visitar oGitHub project.