Рубрики
Без рубрики

Руководство по API асинхронных каналов Java NIO2

Краткое и практическое руководство по API асинхронных каналов NIO2 в Java.

Автор оригинала: baeldung.

1. Обзор

В этой статье мы рассмотрим основы одного из ключевых дополнительных API нового ввода – вывода (NIO2) в Java 7 – API асинхронного канала .

Это первая статья в серии статей, которые будут посвящены этой конкретной теме.

API асинхронного канала являются усовершенствованием более ранних новых API ввода-вывода (NIO), поставляемых с Java 1.4. Чтобы прочитать о селекторах NIO, перейдите по этой ссылке .

Еще одним усовершенствованием API NIO является новый API файловой системы. Вы также можете прочитать больше о его файловых операциях и операциях с путями на этом сайте.

Чтобы использовать асинхронные каналы NIO2 в наших проектах, мы должны импортировать пакет java.nio.channels , поскольку в него включены необходимые классы:

import java.nio.channels.*;

2. Как работают API асинхронных каналов

API – интерфейсы асинхронных каналов были введены в существующий пакет java.nio.channels , проще говоря, путем префикса имен классов со словом Асинхронный .

Некоторые из основных классов включают: AsynchronousSocketChannel , AsynchronousServerSocketChannel и AsynchronousFileChannel .

Как вы, возможно, заметили, эти классы похожи по стилю на стандартные API-интерфейсы NIOchannel.

Кроме того, большинство операций API, доступных классам NIOchannel, также доступны в новых асинхронных версиях. Основное отличие заключается в том, что новые каналы позволяют выполнять некоторые операции асинхронно .

Когда операция инициируется, API асинхронного канала предоставляют нам две альтернативы для мониторинга и управления ожидающими операциями. Операция может вернуть java.util.concurrent.Будущий объект или мы можем передать ему java.nio.channels.completionHandler .

3. Будущий Подход

Объект Future представляет собой результат асинхронного вычисления. Предполагая, что мы хотим создать сервер для прослушивания клиентских подключений, мы вызываем статический open API на AsynchronousServerSocketChannel и при необходимости привязываем возвращенный канал сокета к адресу:

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

Мы передали null , чтобы система могла автоматически назначить адрес. Затем мы вызываем метод accept на возвращаемом сервере SocketChannel :

Future future = server.accept();

Когда мы вызываем accept метод ServerSocketChannel в старом IO, он блокируется до тех пор, пока входящее соединение не будет получено от клиента. Но accept метод AsynchronousServerSocketChannel сразу же возвращает Future объект.

Общий тип объекта Future – это возвращаемый тип операции. В нашем случае выше это AsynchronousSocketChannel , но с таким же успехом это может быть Integer или String , в зависимости от конечного типа возврата операции.

Мы можем использовать объект Future для запроса состояния операции:

future.isDone();

Этот API возвращает true , если базовая операция уже завершена. Обратите внимание, что завершение в этом случае может означать обычное завершение, исключение или отмену.

Мы также можем явно проверить, была ли операция отменена:

future.isCancelled();

Он возвращает true только в том случае, если операция была отменена до завершения в обычном режиме, в противном случае он возвращает false . Отмена производится методом отмена :

future.cancel(true);

Вызов отменяет операцию, представленную объектом Future . Параметр указывает, что даже если операция началась, она может быть прервана. После завершения операции она не может быть отменена

Чтобы получить результат вычисления, мы используем метод get :

AsynchronousSocketChannel client= future.get();

Если мы вызовем этот API до завершения операции, он будет заблокирован до завершения, а затем вернет результат операции.

4. Подход completionHandler

Альтернативой использованию Future для обработки операций является механизм обратного вызова с использованием класса completionHandler . Асинхронные каналы позволяют указать обработчик завершения для использования результата операции:

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
      }
  });

API completed callback вызывается при успешном завершении операции ввода-вывода. Обратный вызов failed вызывается, если операция завершилась неудачно.

Эти методы обратного вызова принимают другие параметры – чтобы позволить нам передавать любые данные, которые, по нашему мнению, могут быть подходящими для маркировки вместе с операцией. Этот первый параметр доступен в качестве второго параметра метода обратного вызова.

Наконец, четкий сценарий – использование одного и того же completionHandler для разных асинхронных операций. В этом случае нам было бы полезно пометить каждую операцию, чтобы обеспечить контекст при обработке результатов, которые мы увидим в действии в следующем разделе.

5. Заключение

В этой статье мы рассмотрели вводные аспекты API асинхронных каналов Java NIO2.

Чтобы получить все фрагменты кода и полный исходный код для этой статьи, вы можете посетить проект GitHub .