Java 用 Cloud クライアント ライブラリで仮想スレッドを構成する

JDK 21 で一般提供された仮想スレッドにより、高並行アプリケーションの開発が簡素化されます。主なメリットは次のとおりです。

  • スループットの向上(特にブロッキング I/O オペレーションを使用するアプリケーション)。
  • 軽量であるため、メモリの最適化が可能です。
  • アプリケーションをリクエストごとのスレッド スタイルで表現できるシンプルな同時実行モデル。

アプリケーションに仮想スレッドを適用する前に、Open JDK ドキュメントの JEP 444: 仮想スレッドで、この機能のメリットと制限事項の両方について詳しく説明しています。

このガイドでは、googleapis/google-cloud-java リポジトリJava 用 Cloud クライアント ライブラリを構成して仮想スレッドを使用する方法について説明します。

前提条件

アプリケーションで使用する Java 用 Cloud クライアント ライブラリで仮想スレッドを使用するには、次の前提条件の手順を行います。

  1. まだ作成していない場合は、 Google Cloud プロジェクトを作成します。プロジェクトの作成と管理をご覧ください。
  2. Google Cloud CLI をインストールします。これにより、プロジェクトの認証情報を使用してサンプルを実行できます。
  3. 次のコマンドを使用して、アプリケーションのデフォルト認証情報でログインします。手順については、アプリケーションのデフォルト認証情報を設定するをご覧ください。

    gcloud auth application-default login
    
  4. Java Development Kit(JDK)21 以降がインストールされていることを確認するには、java -version コマンドを実行し、次の出力が表示されることを確認します。JDK をインストールする手順については、Java 開発環境の設定をご覧ください。

    openjdk version "21.0.2" 2024-01-16 LTS
    OpenJDK Runtime Environment Temurin-21.0.2+13 (build 21.0.2+13-LTS)
    OpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13-LTS, mixed mode, sharing)
    

ライブラリをプロジェクトにインポートする

この例では google-cloud-translate を使用しています。Maven または Gradle でライブラリを使用する手順については、Java 用 Cloud Translation を使用するをご覧ください。

クライアント ライブラリで仮想スレッド エグゼキュータを使用する

クライアント ライブラリ クラスをインスタンス化するときに、トランスポート実装(gRPC と REST)を選択できます。

REST トランスポート

REST トランスポートを実装するクライアント ライブラリは、ブロッキング ネットワーク I/O 呼び出しを使用します。これは、仮想スレッドによって提供されるスループットの改善のメリットがあります。次のコード スニペットは、Java 用 Cloud クライアント ライブラリでのネットワーク I/O トラフィックのブロックを仮想スレッドで管理する方法を示しています。これは、TransportChannelProvider インスタンスでデフォルトのエグゼキュータを仮想スレッド エグゼキュータでオーバーライドすることで、独自のアプリケーションに実装できます。

import com.google.cloud.translate.*;
import java.util.concurrent.Executors;

ExecutorService virtualThreadExecutor = Executors.newVirtualThreadPerTaskExecutor();
InstantiatingHttpJsonChannelProvider httpJsonChannelProvider =
        TranslationServiceSettings.defaultHttpJsonTransportProviderBuilder()
            // Use virtual threads for network I/O calls.
            .setExecutor(virtualThreadExecutor)
            .build();

try (TranslationServiceClient client =
    TranslationServiceClient.create(
        TranslationServiceSettings.newHttpJsonBuilder()
            .setTransportChannelProvider(httpJsonChannelProvider)
            .build())) {
  // Make translate requests
}

gRPC トランスポート

gRPC はすでに非同期ロジックを使用してリクエストを処理しているため、仮想スレッドによるスループットの改善はそれほど顕著ではない可能性があります。ただし、軽量であるため、メモリの最適化にはある程度の効果があります。次のコード スニペットは、仮想スレッドで gRPC トランスポート オペレーションを管理する方法を示しています。これは、TransportChannelProvider インスタンスの仮想スレッド エグゼキュータでデフォルトのエグゼキュータをオーバーライドすることで、独自のアプリケーションに実装できます。

import com.google.cloud.translate.*;
import java.util.concurrent.Executors;

ExecutorService virtualThreadExecutor = Executors.newVirtualThreadPerTaskExecutor();
InstantiatingGrpcChannelProvider grpcChannelProvider =
        TranslationServiceSettings.defaultGrpcTransportProviderBuilder()
            // Use virtual threads for gRPC transport operations.
            .setExecutor(virtualThreadExecutor)
            .build();

try (TranslationServiceClient client =
        TranslationServiceClient.create(
            TranslationServiceSettings.newBuilder()
                .setTransportChannelProvider(grpcChannelProvider)
                .build())) {
  // Make translate requests
}