JDK-8284169 : Implementation of Virtual Threads (Preview)
  • Type: CSR
  • Component: core-libs
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 19
  • Submitted: 2022-04-01
  • Updated: 2022-11-15
  • Resolved: 2022-05-05
Related Reports
CSR :  
Relates :  
Description
This is the CSR for JEP 425: Virtual Threads (Preview) (JDK-8277131).

Summary
-------

Introduce virtual threads to the Java Platform. Virtual threads are lightweight threads that dramatically reduce the effort of writing, maintaining, and observing high-throughput concurrent applications.


Problem
-------

The goal of the JEP is to enable server applications written in the simple thread-per-request style to scale. Unfortunately, the number of threads is limited because the JDK implements `java.lang.Thread` as a thin wrapper over operating system threads. The Motivation section of the JEP provides a lot of discussion on this topic and how some developers workaround the limitation by giving up on the thread-per-request style in favor of thread-sharing and the asynchronous style.


Solution
--------

Introduce a lightweight implementation of threads that are provided by the JDK rather than the OS. This allows developers to write clear code in the thread-per-request style. The JEP provides lengthy discussion of the proposed solution.


Specification
-------------

The specdiffs for the Java APIs, JNI spec, JVM TI spec, and JDWP spec are attached.

The Java API changes proposed include both SE and JDK-specific APIs. A number of APIs are proposed as preview APIs, a number of APIs are proposed as permanent APIs, one method in j.l.Thread is deprecated, and several terminally deprecated in j.l.ThreadGroup are degraded. No APIs are removed.

The Java APIs include new methods on `j.u.concurrent.ForkJoinPool` and `j.u.concurrent.ForkJoinTask`. Prof. Doug Lea is working on a PR and CSR proposing to add these methods in Java 19, in which case they will drop-off the list of API changes here.

The other interface changes in the JEP are JDK-specific:

- New system properties. The system properties for configuration/tuning are documented in an implNote in the Thread class description
    - jdk.virtualThreadScheduler.parallelism (for tuning)
    - jdk.virtualThreadScheduler.maxPoolSize (for tuning)
    - jdk.tracePinnedThreads (for diagnostics)

- New jdb command line option, documented in usage printed by `jdb -help`
    - -trackvthreads    track virtual threads as they are created

- New JDWP agent option, documented in usage printed by `-agentlib:jdwp=help`
    - enumeratevthreads=y|n            thread lists include all vthreads, defaults to n

- New jcmd command, documented in usage printed by `jcmd <pid> help Thread.dump_to_file`
    - jcmd Thread.dump_to_file [-format=json] [-overwrite] file

- New thread dump in JSON format, intended for tools to parse.

- New JFR events:
    - jdk.VirtualThreadStart
    - jdk.VirtualThreadEnd
    - jdk.VirualThreadPinned
    - jdk.VirtualThreadSubmitFailed
Comments
I've refreshed the CSR (attachment loom-20220505.zip). The changes since loom-20220428 are: Doug Lea has integrated JDK-8277090. This reduces the changes to j.u.concurrent in this CSR to 2 static factory methods on j.u.concurrent.Executors. The struct in the "Interface Function Table" section of the JNI spec is updated to list IsVirtualThread. Note that this CSR does propose to add JNI_VERSION_19 to the JNI spec (and jni.h). A separate CSR may propose this.
15-07-2022

I have updated the "Compatibility Risk" section to list source compatibility issue that has turned up since integration (JDK-8287968). The conflict in that bug report is with nested interfaces, and specifically with java.lang.Thread.Builder and javax.ws.rs.sse.OutboundSseEvent.Builder when compiling code that extends Thread and uses the simple name "Builder" in the subclass implementation. This is an example of the source compatibility issues that can arise when adding nested class or interface to a non-final class.
14-06-2022

Moving updated request to Approved.
05-05-2022

IsVirtualThread is in the JNI function table (struct JNINativeInterface) but the struct in the "Interface Function Table" section of the spec should be updated to reflect that. Well spotted! WrongThreadException is proposed as permanent so that it can be used by any API that implements thread confinement. So generally useful like IllegalCallerException. It could be a preview API if you feel it is not ready to be permanent. JDI OpaqueFrameException is proposed to to permanent. The JVMTI/JDWP equivalent are JVMTI_ERROR_OPAQUE_FRAME and JDWP OPAQUE_FRAME have existed since Java 5 and earlier in the case of JDWP.
05-05-2022

Should IsVirtualThread be listed in the JNI JNINativeInterface struct? Should WrongThreadException be a preview class? OpaqueFrameException?
05-05-2022

I've refreshed the CSR (attachment loom-20220428.zip). The changes since loom-20220426 are: java.lang.management.ThreadMXBean - findDeadlockedThreads and findMonitorDeadlockedThreads are updated to make it clear that only cycles of platform threads in deadlock are returned. Previously the spec allowed for ID of platform threads in a deadlock cycle with virtual threads to be returned. com.sun.management.HotSpotDiagnosticMXBean - dumpThreads declares that UnsupportedOperationException can be thrown. The default implementation is specified to throw this exception but it was missed from the throws list. JVM TI - The Thread section of the spec now specifies that JVMTI_ERROR_UNSUPPORTED_OPERATION is returned by functions when an operation is not supported. This section was missed when the error was added.
28-04-2022

I've refreshed the CSR (attachment loom-20220426.zip). The changes since loom-20220401 are: java.lang.Thread - Class description updated. The "Inheritance" section is renamed to "Inheritance when creating threads" and expanded to describe the inherited access control context. - Class description has an implNote to document the system properties that can be used to tune the virtual thread scheduler. - Thread.ofPlatform has new section to describe interaction with the legacy SecurityManager when creating threads. java.lang.ThreadGroup. - Class description has new section "Thread groups and virtual threads" to describe the TG returned by Thread::getThreadGroup when invoked on a virtual thread. - setMaxPriority does not change the max priority of the special group for virtual threads. - The term "active" has been removed from the description of the activeCount/enumerate to make the descriptions clearer. java.lang.WrongThreadException - changed to be final. java.lang.ref.ReferenceQueue - Drop IllegalArgumentException from remove(long) method as it's a runtime exception. java.util.concurrent - CSR JDK-8285450 is in progress to bring the j.u.concurrent API into the main line. It may be integrated before JEP 425. JDI - OpaqueFrameException changed to be sealed, permits NativeMethodException. JDWP - ThreadReference/Stop changed to return NOT_IMPLEMENTED (was INVALID_THREAD) when the thread ID is a virtual thread. JVMTI - New error UNSUPPORTED_OPERATION. - StopThread, RunAgentThread, GetCurrentThreadCpuTime, and GetThreadCpuTime changed to return this error (was INVALID_THREAD) when the jthread is a virtual thread.
28-04-2022

I have reviewed at the serviceability JDI/JDWP/JVMTI specdiffs and they look good to me.
28-04-2022

Reviewed java.lang and java.lang.ref.
28-04-2022

Went over the APi specdiff, it looks great to me overall.
27-04-2022

I went over the specdiff, it looks good to me. I have not looked at JDI/JDWP/JVMTI as there are other reviewers more qualified than me for these parts. I assume you will be uploading a new specdiff before finailizing - as the HotspotDiagnosticMXBean has acquired an `@throws UnsupportedOperationException` in its new methods since the last specdiff was uploaded.
27-04-2022

Thanks for looking at this CSR and moving it to Provisional. Just on the comments: WrongThreadException can be final. It could also be added in advance of the JEP and used in other contexts, e.g. APIs that are thread confined in Panama. The concern with renaming the threadId method to "systemThreadId" is developers may read is as "system thread". It may get confused with the notion of "system threads" (threads in the top-level thread group) in SecurityManager and ThreadGroup API docs. ForkJoinPool. I assume the comment is about the limit mention in the IllegalArgumetException description. JDI OpaqueFrameException could be sealed. NativeMethodException has been retrofitted to extend the new exception so that exception would need to be non-sealed.
05-04-2022

Thank you to [~alanb] and the Loom team for filing the CSR early; moving to Provisional. Comments: Can WrongThreadException be final initially (or sealed if it has internal subclasses)? Thread.threadId() -- consider "systemThreadId" like "System.identityHashCode"? Since ForkJoinPool is subclassable, the implementation limits in setParallelism would be better expressed an an implNote. Should OpaqueFrameException be sealed?
05-04-2022