A New Early Access Build

Ron Pressler ron.pressler at oracle.com
Thu Dec 19 10:23:08 UTC 2019


We have just published a new -- our second -- Early Access build:


This build represents a drastic departure from the API in the first EA builds.
We don't expect further radical changes in the short term, so we may be able to
publish EA builds on a more regular basis.


This prototype has the new API we introduced in October, that represents Loom's
lightweight user-mode threads as instances of java.lang.Thread [1]; the
rationale for that decision is explained in [2]. We are now calling Loom's
lightweight user-mode threads "virtual threads" [3].

Virtual threads can be created with the newly-introduced Thread.Builder class.
It can be used to directly build Thread instances, or to create a ThreadFactory
instance. For example:

    Thread thread = Thread.builder().virtual().task(() -> { ... }).start();

Thread.Builder exposes other settings we're experimenting with, like optionally
disallowing the use of ThreadLocal.

The previous EA build introduced structured concurrency [4]. In the updated
prototype, a more limited form of a structured concurrency can be achieved with
ExecutorService; for example:

    ThreadFactory factory = Thread.builder().virtual().factory(); 
    try (ExecutorService executor = Executors.newUnboundedExecutor(factory)) {

The new Executors.newUnboundedExecutor method creates an ExecutorService that
spawns a new thread for each submitted task -- in this case, a virtual thread
constructed by the provided factory.

Please consult the Javadoc [5] for details.


We have begun work to improve performance. The performance of virtual threads is
a result of three components: the implementation of continuations in the VM, the
implementation of the scheduler (recall: thread = continuation + scheduler), and
tuning the concurrency constructs in java.util.concurrent to work well with
virtual threads. So far we've started addressing the first component, and this
build contains a new implementation of continuations. By default, the old
implementation is used; to use the new one, launch your application with the
flag -XX:+UseContinuationChunks. Depending on your code, you may or may not see
a difference in performance due to the other two components. To reduce the
effect of the as-yet-untuned scheduler, use a scheduler with a single worker
(carrier) thread. If you are using the default scheduler (by creating the thread
with no-argument Thread.builder().virtual() method), this can be done by
supplying the flag -Djdk.defaultScheduler.parallelism=1.

Because we are starting to address performance, we are now ready to accept
benchmarks, preferably those that you think might represent workloads you are
interested in. If you think you have a benchmark that could be of interest for
optimization, please submit it to the mailing list. This can be a benchmark with
what you consider to be unexpectedly bad performance, or just some workload you
find important for your particular use-cases of virtual threads.

I'd like to remind you that virtual threads have the (hopefully temporary)
limitation that blocking the thread on IO while holding a monitor (i.e. inside
a synchronized method or block) will block the underlying carrier kernel thread
(as do calls to Object.wait()). This should only impact performance if done 
frequently. To detect when a virtual thread is "pinned" to the carrier thread 
and cannot release it due to a held monitor, add either the 
-Djdk.tracePinnedThreads=full or -Djdk.tracePinnedThreads=short flag.


You should be able to debug (step-through and inspect) virtual threads in jdb or
an IDE. Some operations are not supported. Please share your experience: Does it
fit your expectations or is the behavior surprising?

Profiling and Monitoring

We have only begun work to support virtual threads in JFR, and this build does
not yet contain any support for virtual threads.


Continuations are the low-level VM mechanism used to implement virtual threads 
in the core libraries. The Continuation class will likely become non-public in 
a future build (whether and how to expose continuations will be debated at some 
later time), but it is currently still public. Due to internal changes, nested 
continuation scopes currently crash the VM; this will be fixed soon.


This prototype is far from stable, and you can expect VM crashes. If you
encounter them, please submit a reproduction and the resulting hs_err file to
the mailing list. We will start addressing stability issues in the new year.


Most of the Loom team will be out on vacation for the next couple of weeks, so
responses may be sparse; don't let that keep you from posting your reports.

Happy holidays!

- Ron

[1]: https://mail.openjdk.java.net/pipermail/loom-dev/2019-October/000825.html

[2]: https://mail.openjdk.java.net/pipermail/loom-dev/2019-October/000825.html

[3]: https://mail.openjdk.java.net/pipermail/loom-dev/2019-November/000864.html

[4]: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/

[5]: https://download.java.net/java/early_access/loom/docs/api/

More information about the loom-dev mailing list