Open10

Java Virtual Thread の調査とユースケース検討

iwatakaiwataka

Virtual Threadの大きな特徴として、公式ページには以下のように書かれている。

Like a platform thread, a virtual thread is also an instance of java.lang.Thread. However, a virtual thread isn't tied to a specific OS thread. A virtual thread still runs code on an OS thread. However, when code running in a virtual thread calls a blocking I/O operation, the Java runtime suspends the virtual thread until it can be resumed. The OS thread associated with the suspended virtual thread is now free to perform operations for other virtual threads.

Virtual Threadは特定のOSスレッドに紐づかず、ブロッキングI/Oが発生した場合には処理を中止し、別のVirtual Threadを処理する事ができるということで、ノンブロッキングなマルチスレッド処理を実装できるようだ。

iwatakaiwataka

一見すると、Javaにとってこれは大きな進歩で、Webシステムや多くのI/Oが発生するバッチ処理等で大きな性能向上が見込めそうな内容となっている。

iwatakaiwataka

しかし、他のプログラミング言語の例としてPythonを考えてみると、少なくとも3.7(2018年6月)の頃からノンブロッキングなマルチスレッド処理が機能として提供されている。

https://docs.python.org/3.7/library/threading.html

However, threading is still an appropriate model if you want to run multiple I/O-bound tasks simultaneously.

※逆にPythonはGILの制約により、基本的にOSのスレッドが1つしか利用できない

iwatakaiwataka

そう考えると、Javaが今までノンブロッキングなマルチスレッド処理の機能を提供できていなかったということに違和感を覚えたので、まずは一例として、JavaのWebシステムでよく使われるApache Tomcatの仕様を少し調べてみるとことにした。

iwatakaiwataka

https://tomcat.apache.org/

The Apache Tomcat Project is proud to announce the release of version 10.1.13 of Apache Tomcat. This release implements specifications that are part of the Jakarta EE 10 platform.

Tomcatの現在の最新バージョンは10で、Jakarta EE 10 platformの仕様に則って実装されているようだ。

iwatakaiwataka

Jakarta Servlet 6.0の「2.3.3.3. Asynchronous processing」の部分を確認すると、以下のような記載があった。

https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0#asynchronous-processing

Sometimes a filter and/or servlet is unable to complete the processing of a request without waiting for a resource or event before generating a response. For example, a servlet may need to wait for an available JDBC connection, for a response from a remote web service, for a JMS message, or for an application event, before proceeding to generate a response. Waiting within the servlet is an inefficient operation as it is a blocking operation that consumes a thread and other limited resources. Frequently a slow resource such as a database may have many threads blocked waiting for access and can cause thread starvation and poor quality of service for an entire web container.

The asynchronous processing of requests is introduced to allow the thread to return to the container and perform other tasks. When asynchronous processing begins on the request, another thread or callback may either generate the response and call complete or dispatch the request so that it may run in the context of the container using the AsyncContext.dispatch method.

どうやらサーブレットの仕様として、I/O待ちによる非効率な処理に対する対策が取られているようだ。

iwatakaiwataka

そう考えると、現状TomcatなどのWebコンテナを利用しているWebシステムは、Virtual Threadを利用してもそれほど性能は変わらないのだろうか?
それともサーブレットの仕様・実装とVirtual Threadの間には自分が知らない差分があって、Virtual Threadを利用するとなにか恩恵を受けられるのだろうか?

その当たりは気になるところである。

iwatakaiwataka

おそらくだが、Virtual Threadという概念・機能自体は革新的なものでは全然なくて、それに近い実装は色んなところで既にされているんだと思う。

それがJavaのコア機能として提供された、というのが今回のポイントなのではなかろうか。