Java9パート4-リアクティブストリームAPIリアクティブプログラミング

ファイル

次の期間にJava9に関する一連の記事を書く予定です。Java9はJava8やJava11のようなコアJavaバージョンではありませんが、注目に値する機能はまだたくさんあります。皆様のご注目をお待ちしております。Java9に関する一連の記事を約10件お書きします。

Java9のReactiveStreamsは、非同期ストリーミングプログラミングの実装です。これは、非同期のパブリッシュおよびサブスクライブモデルに基づいており、ノンブロッキングの「バックプレッシャ」データ処理の特性を備えています。

ノンブロッキングバックプレッシャー:これは、パブリッシュアンドサブスクライブモデルのサブスクライバーが(処理能力を超えて)大量のデータを受信しないようにするメカニズムであり、サブスクライバーは非同期でパブリッシャーに通知して、データの生成とリリースを増減できます。 s速度。効果を達成するためのレスポンシブプログラミングのコア機能です!

一、Java9リアクティブストリームAPI

Java 9は、リアクティブストリームプログラミングを定義するための一連のインターフェイスを提供します。これらのインターフェースはすべて、静的内部インターフェースとしてjava.util.concurrent.Flowクラスで定義されています

ファイル

以下は、Javaリアクティブプログラミングにおけるいくつかの重要な役割と概念です。最初に簡単に理解してください。

  • パブリッシャーは、潜在的に無制限の数の順序付けられたデータ要素のプロデューサーです。受信した需要(サブスクリプション)に応じて、現在のサブスクライバーに特定の数のデータ要素を公開します。
  • サブスクライバー(サブスクライバー)は、パブリッシャーからデータ要素をサブスクライブして受信します。パブリッシャーとのサブスクリプション関係を確立した後、パブリッシャーはサブスクリプショントークン(サブスクリプション)をサブスクライバーに送信し、サブスクライバーは、処理能力に応じてデータ要素の数を公開するようにパブリッシャーに要求できます。
  • サブスクリプショントークン(サブスクリプション)は、サブスクライバーとパブリッシャーの間で確立されたサブスクリプション関係を表します。サブスクリプション関係が確立されると、パブリッシャーはそれをサブスクライバーに渡します。サブスクライバーは、サブスクリプショントークンを使用して、データ要素の数を要求したり、サブスクリプションをキャンセルしたりするなど、パブリッシャーと対話します。

2つ目は、Javaリアクティブプログラミングの4つの主要なインターフェイスです。

2.1。サブスクライバーインターフェイス(サブスクライバーサブスクリプションインターフェイス)

public static interface Subscriber<T> {
    public void onSubscribe(Subscription subscription);
    public void onNext(T item);
    public void onError(Throwable throwable);
    public void onComplete();
}
  • onSubscribe:パブリッシャーがサブスクライバーのサブスクリプションアクションを受け入れた後、サブスクリプションメッセージを公開する前に呼び出されます。新しく作成されたSubscriptionサブスクリプショントークンオブジェクトは、このメソッドを介してサブスクライバーに渡されます。
  • onNext:次に処理されるデータ項目の処理機能
  • onError:パブリッシャーまたはサブスクリプションで回復不能なエラーが発生したときに呼び出されます
  • onComplete:サブスクライバー呼び出し(onNext()メソッドを含む)が発生しない場合に呼び出されます。

2.2。サブスクリプションインターフェイス(サブスクリプショントークンインターフェイス)

サブスクリプショントークンオブジェクトはSubscriber.onSubscribe()メソッドを介して渡されます

public static interface Subscription {
    public void request(long n);
    public void cancel();
}
  • request(long n)これは、非ブロッキング背圧の概念の背後にある重要な方法です。サブスクライバーはこれを使用して、n個を超える消費アイテムを要求します。このようにして、サブスクライバーは現在受信できるデータの量を制御します。
  • cancel()サブスクライバーは、サブスクリプションをキャンセルするイニシアチブを取り、キャンセル後にデータメッセージを受信しません。

2.3。パブリッシャーインターフェイス(パブリッシャーインターフェイス)

@FunctionalInterface
public static interface Publisher<T> {
    public void subscribe(Subscriber<? super T> subscriber);
}

このメソッドを呼び出して、サブスクライバーサブスクライバーとパブリッシャーパブリッシャー間のメッセージサブスクリプション関係を確立します。

2.4。プロセッサインターフェイス(プロセッサインターフェイス)

プロセッサは、サブスクライバーとパブリッシャーとして同時に機能し、パブリッシャーとサブスクライバーのパイプラインの要素を変換する役割を果たします。タイプTのデータ要素を受信して​​タイプRのデータに変換し、公開するために使用されます。

public static interface Processor<T,R> extends Subscriber<T>, Publisher<R> {
}

2.実際のケース

次に、上記の4つのインターフェイスを実装して、リアクティブプログラミングを完了します。

  • サブスクリプションインターフェイスサブスクリプショントークンインターフェイスは通常、実装するために独自のプログラミングを必要とせず、request()メソッドとcancle()メソッドの意味を知る必要があるだけです。
  • パブリッシャーインターフェイスパブリッシャーインターフェイスであるJava9は、デフォルトでSubmissionPublisherの実装を提供します。パブリッシャーインターフェイスを実装するメソッドに加えて、この実装クラスは、submit()メッセージデータの送信を完了するために呼び出されるメソッドを提供します。
  • サブスクライバーインターフェイスサブスクライバーインターフェイス。通常、自分で実装する必要があります。データサブスクリプションを受け取った後は、ビジネスごとに処理ロジックが異なるためです。
  • プロセッサは、実際にはパブリッシャーインターフェイスとサブスクライバーインターフェイスのコレクションです。このインターフェイスを実装するには、データ型の変換とデータ処理が必要です。

次の例は、タイプ文字列のデータメッセージサブスクリプション処理を実装します

サブスクライバーインターフェイスの実装

import java.util.concurrent.Flow;

public class MySubscriber implements Flow.Subscriber<String> {

  private Flow.Subscription subscription;  //订阅令牌

  @Override
  public void onSubscribe(Flow.Subscription subscription) {
      System.out.println("订阅关系建立onSubscribe: " + subscription);
      this.subscription = subscription;
      subscription.request(2);
  }

  @Override
  public void onNext(String item) {
      System.out.println("item: " + item);
      // 一个消息处理完成之后,可以继续调用subscription.request(n);向发布者要求数据发送
      //subscription.request(n);
  }

  @Override
  public void onError(Throwable throwable) {
      System.out.println("onError: " + throwable);
  }

  @Override
  public void onComplete() {
      System.out.println("onComplete");
  }
}

SubmissionPublisherメッセージ発行者

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;

public class SubmissionPublisherExample {
  public static void main(String[] args) throws InterruptedException {
      ExecutorService executor = Executors.newFixedThreadPool(1);
      SubmissionPublisher<String> sb = new SubmissionPublisher<>(executor, Flow.defaultBufferSize());
      sb.subscribe(new MySubscriber());   //建立订阅关系,可以有多个订阅者
      sb.submit("数据 1");  //发送消息1
      sb.submit("数据 2"); //发送消息2
      sb.submit("数据 3"); //发送消息3

      executor.shutdown();
  }
}

コンソールは結果を出力します

订阅关系建立
onSubscribe: java.util.concurrent.SubmissionPublisher$BufferedSubscription@27e81a39
item: 数据 1
item: 数据 2

注意:発行者が3つのデータを送信した場合でも、MySubscriberは処理のために2つのデータしか受信しません。MySubscriber#onSubscribe()メソッドで使用したためですsubscription.request(2);これは「バックプレッシャー」のレスポンシブプログラミング効果です。処理できるデータの量に応じて、メッセージの発行者にデータの量を通知します。

私のブログをフォローすることを歓迎します、多くのブティックコレクションがあります

  • この記事は、出典を示して複製されています(接続を添付する必要があり、テキストのみを複製することはできません):レターブラザーのブログ

あなたがそれがあなたに役立つと思うなら、私のためにそれを好きにして共有してください!あなたのサポートは私の尽きることのない創造的な動機です!また、最近、以下のような高品質なコンテンツを出力しておりますので、よろしくお願いいたします。

おすすめ

転載: blog.csdn.net/hanxiaotongtong/article/details/109128389