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.