TechFeed Conference 2022 Pick up

Java 19の注目新機能Virtual Threadについて ~TechFeed Conference 2022講演より

本記事は、2022年5月に開催されたTechFeed Conference 2022のセッション書き起こし記事「Java 19 の注目新機能 Virtual Thread について(てらだ よしお⁠⁠ — TechFeed Conference 2022講演より」を転載したものです。オリジナルはTechFeedをご覧ください。

皆さん、こんにちは。Microsoftの寺田です。今日はJavaの最新動向についてご紹介していきたいと思います。どうぞよろしくお願いいたします。

まず最初にこちらをご覧ください。

Javaのロードマップについて

2017年にJava 9をリリースして以降、Javaは半年に1度、アップデートするようになりました。

企業環境において、多くのJavaの利用者は、Java 11とかJava 17といったロングターム(長期間)サポート付きのバージョンに移行される方が多いかとは思います。

次のLTSバージョンですが、来年9月にJava 21がリリースされる予定です。また、Java 21がリリースされる前にも、半年に1度、アップデートが行われます。

現在はJava 18がリリースされていますが、今年の9月には新しいJava 19というバージョンがリリースされる予定です。

Java 19について

私が今回注目をする(Java 19の)新機能ですが、こちらにあるようにJEP425のバーチャル・スレッド(仮想スレッド)になります。

JEP425:仮想スレッド

仮想スレッドは、非常に軽量で簡単に作成することができて、大量の処理で負荷のかかるようなアプリケーション、あとは並列処理などでとても大きな威力を発揮するのではないかと思います。

それでは、なぜこの仮想スレッドという軽量なスレッドが新機能として追加されているのかについて、これからご紹介していきたいと思います。

まずこちらをご覧ください。

Javaの今までのスレッド・モデル

今までのJavaのスレッドというものは、1つスレッドを生成するとネイティブ側のほうでも同じように1対1で対応するスレッドが生成されました。OSで管理するネイティブスレッドというものは、システムコールを呼び出して作成したり、スケジューリングをカーネル側でやったりと、けっこう負荷がかかるんですね。

それに1つスレッドを作ると、スタックでメモリを消費したり、あと CPU のコア数を超える大量にスレッドを作ると、スレッドをどのCPUコアで動かすのか、それを切り替えるためのコンテキストスイッチというものがたくさん発生します。

こういったことが、今まで起こっていたわけなんですが、今後どうなるのかというと、Javaの仮想スレッドというものをご利用いただくことで、Javaのバーチャルマシンの中でスレッドを作成したり管理できるようになります。つまりネイティブスレッドに比べて少ないメモリで高速にスレッドを作成することができます。

Javaの仮想スレッド

ですので、大量にリクエストが来るようなWebサーバの実装であったり、あとは pub/sub で大量のメッセージを送受信したりといったことを各スレッドでやりたい場合は、仮想スレッドでの実装が非常に有効的になるんじゃないかなと思います。

まとめると、仮想スレッドは、多くの時間がブロックされてI/Oの操作が完了するような、ずっと待っているようなタスクの実行に向いていますが、大量の計算が必要な処理にはあまり向いていないので、ケースバイケースでお使いいただけると嬉しいな、と思います。

Java 19のデモ

それでは、実際にJava19のデモを行っていきたいと思います。

実際にバーチャルスレッドを作成する方法はいろいろあるんですが、今回は、ふだん皆様がよくお使いいただいている、Executorサービスを使ってバーチャルスレッドを作っていきたいと思います。

newThreadPerTaskExecutor() というメソッドは、Java 19で追加されたメソッドなんですが、この中で仮想スレッドを作って実行します。具体的に何をやっているかと言うと、100万回ループを回して、その中でタスク毎に100万個のスレッドを作り、何らかの処理を実行するという処理を実装しています。

デモ:newThreadPerTaskExecutor()

このメソッドを呼び出す際に使うThread.Builderは、Java 19で追加されたインターフェースのThread.ofVirtualとThread.ofPlartformという2つのインターフェースを利用して生成します。そして、今回のデモではこれらを使い分けて検証を行います。

デモ:Thread.ofVirtualとThread.ofPlartform

それでは、まずThread.OfPlatform()でThread.Builderを生成し、プラットフォーム・スレッドを作成し実行します。これを実行すると、すぐにOutOfMemoryエラーが発生するんですね。

デモ:プラットフォーム・スレッドでOutOfMemoryエラー

OutOfMemoryエラーは十分なメモリがなくて、スレッドを作成できないということですが、実はメモリが足りていないわけではなく、OS 側で生成可能なスレッド数の上限を超えたために発生しています。このように100万個のOS のユーザ・スレッドを一気に作るということは、ネイティブスレッドでは非常に難しいということですね。

では今度はこれをバーチャルスレッド側で作ってみたいと思います。

Thread.OfVirtual() で Thread.Builder を生成し実行すると、このようにスレッドが OutOfMemoryエラーで停止することなく、最後まで処理を行っていくことができます。

デモ:バーチャルスレッドで実行

今回は時間の都合上、簡単な紹介になってしまいましたが、このJava 19で導入される仮想スレッドを利用することで、場合に応じて、非常に高いスループットが求められるようなサービスで活用していただくことができるかと思います。本当にこれは覚えておいて損はないAPIだと思いますので、ぜひぜひお試しください。

今日は本当にどうもありがとうございました。

おすすめ記事

記事・ニュース一覧