Leitfaden für Java NIO2-APIs für asynchronen Kanal

Leitfaden zu Java NIO2-APIs für asynchrone Kanäle

1. Überblick

In diesem Artikel werden wir die Grundlagen einer der wichtigsten zusätzlichen APIs der neuen E / A (NIO2) in Java 7-asynchronous channel APIsuntersuchen.

Dies ist der erste Teil einer Reihe von Artikeln, die sich mit diesem speziellen Thema befassen.

Die asynchronen Kanal-APIs sind eine Erweiterung der früheren neuen I / O-APIs (NIO), die mit Java 1.4 ausgeliefert wurden. Um mehr über NIO-Selektoren zu erfahren, folgen Sie bittethis link.

Eine weitere Verbesserung der NIO-APIs ist die neue Dateisystem-API. Weitere Informationen zufile operations undpath operations finden Sie auch auf dieser Website.

Um die asynchronen NIO2-Kanäle in unseren Projekten zu verwenden, müssen wir das Paketjava.nio.channelsimportieren, da die erforderlichen Klassen darin gebündelt sind:

import java.nio.channels.*;

2. Funktionsweise von Asynchronous Channel-APIs

Die asynchronen Kanal-APIs wurden einfach in das vorhandene Paketjava.nio.channels eingeführt, indem den Klassennamen das WortAsynchronous vorangestellt wurde.

Einige der Kernklassen umfassen:AsynchronousSocketChannel,AsynchronousServerSocketChannel undAsynchronousFileChannel.

Wie Sie vielleicht bemerkt haben, haben diese Klassen einen ähnlichen Stil wie die Standard-NIO-Kanal-APIs.

Die meisten API-Operationen, die für die NIO-Kanalklassen verfügbar sind, sind auch in den neuen asynchronen Versionen verfügbar. Der Hauptunterschied besteht darin, dassthe new channels enable some operations to be executed asynchronously.

Wenn eine Operation initiiert wird, bieten uns die APIs für asynchrone Kanäle zwei Alternativen zum Überwachen und Steuern der ausstehenden Operationen. Die Operation kann das Objektjava.util.concurrent.Futurezurückgeben oder wir könnenjava.nio.channels.CompletionHandler an das Objekt übergeben.

3. DerFuture Ansatz

A Future object represents a result of an asynchronous computation. Angenommen, wir möchten einen Server zum Abhören von Clientverbindungen erstellen, rufen wir die statischeopen-API aufAsynchronousServerSocketChannel auf und binden den zurückgegebenen Socket-Kanal optional an eine Adresse:

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

Wir habennull übergeben, damit das System automatisch eine Adresse zuweisen kann. Dann rufen wir dieaccept-Methode auf dem zurückgegebenen ServerSocketChannel auf:

Future future = server.accept();

Wenn wir dieaccept-Methode vonServerSocketChannel in der alten E / A aufrufen, wird sie blockiert, bis eine eingehende Verbindung von einem Client empfangen wird. Dieaccept-Methode einesAsynchronousServerSocketChannel gibt jedoch sofort einFuture-Objekt zurück.

Der generische Typ desFuture-Objekts ist der Rückgabetyp der Operation. In unserem obigen Fall ist esAsynchronousSocketChannel, aber es könnte genauso gutInteger oderString sein, abhängig von der endgültigen Rückgabeart der Operation.

Wir können dasFuture-Objekt verwenden, um den Status der Operation abzufragen:

future.isDone();

Diese API gibttrue zurück, wenn die zugrunde liegende Operation bereits abgeschlossen ist. Beachten Sie, dass die Fertigstellung in diesem Fall eine normale Beendigung, eine Ausnahme oder einen Abbruch bedeuten kann.

Wir können auch explizit prüfen, ob der Vorgang abgebrochen wurde:

future.isCancelled();

Es wird nurtrue zurückgegeben, wenn der Vorgang vor dem normalen Abschluss abgebrochen wurde, andernfalls wirdfalse zurückgegeben. Die Stornierung erfolgt nach der Methodecancel:

future.cancel(true);

Der Aufruf bricht die durch dasFuture-Objekt dargestellte Operation ab. Der Parameter zeigt an, dass der Vorgang, selbst wenn er begonnen hat, unterbrochen werden kann. Sobald ein Vorgang abgeschlossen ist, kann er nicht mehr abgebrochen werden

Um das Ergebnis einer Berechnung abzurufen, verwenden wir die Methodeget:

AsynchronousSocketChannel client= future.get();

Wenn wir diese API aufrufen, bevor der Vorgang abgeschlossen ist, wird sie bis zum Abschluss blockiert und anschließend das Ergebnis des Vorgangs zurückgegeben.

4. DerCompletionHandler Ansatz

Die Alternative zur Verwendung von Future zur Abwicklung von Operationen ist ein Rückrufmechanismus unter Verwendung der KlasseCompletionHandler. Über die asynchronen Kanäle kann ein Beendigungshandler angegeben werden, um das Ergebnis einer Operation zu verarbeiten:

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

Die Rückruf-API voncompletedwird aufgerufen, wenn der E / A-Vorgang erfolgreich abgeschlossen wurde. Der Rückruf vonfailedwird aufgerufen, wenn die Operation fehlgeschlagen ist.

Diese Rückrufmethoden akzeptieren andere Parameter - damit wir alle Daten weitergeben können, die wir für geeignet halten, um sie zusammen mit der Operation zu kennzeichnen. Dieser erste Parameter steht als zweiter Parameter der Callback-Methode zur Verfügung.

Ein klares Szenario ist schließlich die Verwendung des gleichenCompletionHandler für verschiedene asynchrone Operationen. In diesem Fall können wir jede Operation mit einem Tag versehen, um bei der Verarbeitung der Ergebnisse einen Kontext bereitzustellen. Dies wird im folgenden Abschnitt in Aktion angezeigt.

5. Fazit

In diesem Artikel haben wir uns mit einführenden Aspekten der Asynchronous Channel-APIs von Java NIO2 befasst.

Um alle Codefragmente und den vollständigen Quellcode für diesen Artikel abzurufen, besuchen Sie dieGitHub project.