A lightweight thread is a Thread

Ron Pressler ron.pressler at oracle.com
Wed Oct 23 21:16:42 UTC 2019


I'd like to briefly explain the reasoning that has led us to this approach.

As is usually the case when introducing a change to an established platform, we
are confronted by two, often opposing, forces:

1. The desire to have as much existing code be "forward compatible" and run with
the new construct -- in this case, lightweight threads.

2. The desire to correct past decisions which were either mistakes or made in an
environment that has since changed, and the wish to shield newcomers from
possibly outdated APIs -- in this case the baggage of the Thread class -- by
starting afresh.

Two observations informed our current position:

1. The use of Thread.currentThread() is pervasive. If we were to follow the
previous approach of lazily creating an adapter Thread instance ("shadow
Thread") that wraps a Fiber, we would see this adapter instantiated in a very
large percentage of cases, and it still wouldn't be entirely transparent, as the
adapter Thread instance would not have the same identity as the corresponding
Fiber instance; this not only negates any footprint gains in those case but
could also lead to subtle errors.

2. Ever since the introduction of java.util.concurrent package we've discouraged
people from using the Thread API directly (mostly of the start and join methods)
anyway.

These observations mean that the new approach -- a lightweight thread is a
Thread (and a heavyweight thread is also a Thread) -- can nicely balance the two
forces, or so we hope. A lot of existing code could run in lightweight threads,
yet most of the interaction with threads would circumvent the Thread API, at
least the parts of it we like less, and would be done through APIs that express
our current thinking about the "right way" of working with threads. The
understanding that Thread's footprint could be drastically reduced without
harming the performance of existing code removes that obstacle as well.

- Ron



On 22 October 2019 at 14:59:32, Alan Bateman (alan.bateman at oracle.com(mailto:alan.bateman at oracle.com)) wrote:

> This project has been trying to figure out the API to expose for
> lightweight threads, and its relationship with the Thread API, for some
> time. There has been many prototypes (lightweight thread = Thread, Fiber
> <: Thread, Fiber and Thread <: Strand, disjoint Fiber and Thread types).
> Thread.currentThread() and thread locals featured in all prototypes as
> it's critical that the current Thread cannot change value in a thread of
> execution.
> 
> I think we are at the point where we are concluding that a lightweight
> thread should be represented by a Thread. No Fiber or other sub-class
> exposed in the API. We'll use the term "lightweight thread" rather than
> "fiber". The approach maintains the mental model of a thread of
> execution that we are familiar with here, and the mental model that
> developers coming to the platform should be able to figure out. The
> Thread API does come with baggage (ThreadGroup, TCCL, ...) but it may
> not be too bad when you consider that most developers don't use the
> Thread API directly. In addition, we can degrade and/or eliminate at
> least some of this baggage over time, starting with the deprecated features.
> 
> Moving to Thread as the API for lightweight threads means we need to
> restart some of the API work. In particular the support for structured
> concurrency and cancellation will need to move aside temporarily as we
> rebuild from the bottom. I will push a change to the "fibers" branch
> soon with the first steps in that direction. The first steps include 4
> static factory methods on Thread to create lightweight threads
> (unnamed/named * default or BYO scheduler). There are several discussion
> points around what lightweight threads support and don't support. For
> now, the default is support thread locals and not inherit thread locals
> but it can overridden by specifying characteristics to the factory
> methods. The API is primitive for now and will likely change many times.
> 
> API aside, one of the benefits of representing a lightweight thread as a
> Thread is that it makes it possible to make progress in the
> serviceability areas that we've had to ignore to date. We can finally
> start to figure how the existing monitoring and management APIs, JFR,
> and diagnostic features might work with lightweight threads. Good
> progress has been made on JVM TI and the debugger support in the last
> year and it shouldn't require too much re-work to get the debugger
> support re-aligned.
> 
> One final thing for now is footprint. There will be some refactoring of
> Thread required to reduce its footprint. The initial changes will move
> some of fields that aren't performance critical to a sidecar/helper
> object. Doug Lea has changes to the FJ code in the works that should
> avoid the need for padding/@Contended on the fields used by
> ThreadLocalRandom. The object size will, at least initially, be a bit
> larger that I had hoped but I'm sure we will improve this in time.
> 
> -Alan.



More information about the loom-dev mailing list