JEP draft: JEP: Scope locals

OwnerAndrew Haley
Created2021/03/04 11:03
Updated2021/03/04 11:34


The original motivation for this enhancement comes from Project Loom. Loom provides lightweight "virtual threads", of which there may be a huge number, potentially in the millions. These virtual threads are designed to have a small footprint, a requirement if we are to create systems with millions of threads.

It is a common pattern to use ThreadLocal instances to convey context information to Threads. However, InheritableThreadLocal is a fairly heavyweight class, and its design requires a parent thread's map of ThreadLocals to be cloned at child thread creation.

Scope locals are a solution to this problem. A Thread instance's set of inheritable scope locals does not need to be cloned when a child thread is created: all that is needed is to pass a pointer to an immutable set of bindings.

Scope locals can be thought of as a structured counterpart of ThreadLocals. A scope local is bound in a scope to a value, and its bound value my be retrieved by any method called (directly or transitively) from within that scope. Once that scope has exited, the scope local is no longer bound to the value: it either becomes unbound, or its bound value reverts to whatever it was prior to entering that scope. If a scope local binding is captured by the creation of a child thread, that binding remains visible to the child even after the parent scope which bound the scope local has exited.

Scope locals are (deliberately) more restricted in their use than ThreadLocals. For example, a ThreadLocal instance can be used to pass information from a (transitive) callee to its caller, which is not possible with a scope local. However, this restriction provides some advantages. For example, scope locals can be inherited by instances of Future or similar classes, providing a powerful mechanism for passing context information to sub-tasks as well as sub-threads. .