Scoped variables

Alan Bateman Alan.Bateman at oracle.com
Sun Dec 9 20:12:58 UTC 2018


On 09/12/2018 15:49, Brian Goetz wrote:
> :
> Right now, we’ve got ThreadLocal.  It is usually used as an approximation for what we really wan but we don’t have.  TL is what we’ve got, so we use it for a lot of things.  Ron and Alan spent some time categorizing the various use cases, and we looked at them and asked which of them are good uses and which are abuses, and for those that are abuses, what a better mechanism might be.  I’ll defer to Ron and Alan to provide a more complete list, but I’ll sketch out some canonical examples from each category (probably forgetting one):
Your list is a good summary. The forgotten one is "task local", 
essentially just extending the task with fields. That one is bit 
limited, at least for library code where there won't be knowledge about 
the task that is running it.

>
>   - Proxy for processor-local
>     - Contention-avoidance schemes
This one is somewhat specialized and too early to say if it make sense 
to expose as an API or not.  For now, it's the "processorid" branch in 
the loom repo where there is an Unsafe method to get the processor id. 
Rickard has done good work on an intrinsic so it compiles to the fastest 
instruction for the processor (linux-x64 only for now). There isn't a 
ProcessorLocal<T> or anything else making use of it at this time as 
there is a lot more investigation and experimentation needed. We're 
hoping Doug will find time to see if j.u.c. could use it, maybe 
Striped64. I assume TLR won't use it and will need to continue to make 
use of TLR fields on the (carrier) Thread.

>   - Proxy for frame-local
>     - Transaction IDs, caller context, etc (EE uses this ubiquitously)
>     - Other framework-specific implicit arguments or context
This is the focus of the discussion in this thread. It's not hard to 
find examples where a framework or library sets a TL with some context 
that is accessed by some callee that is many stack frames from where the 
local was set. A common pattern is set a TL with some context object, 
perform some action that may need the context, and restore/remove the 
local in a finally block. We found several places where there is nesting 
so the setup involves saving the old context before "pushing" the new 
context. The finally block just restores the previous context. There are 
several examples in Jetty and Jersey that do exactly this.

>   - Caches
>     - Objects that are expensive to create, such as SimpleDateFormat
The common pattern seems to be objects that are not thread safe and are 
expensive to create. We've seen many cases where SimpleDateFormat 
objects are cached in a TL. In the JDK, CharsetEncoder/CharsetDecoder 
objects are examples that they cached in several TLs.


> :
>
> (Stepping back further, the bigger goal here is that, if we have the right mechanisms, we don’t have to make such heroic efforts to make fibers support thread locals, meaning that we will get to the fiber mechanism we really want, rather than the one tied to the legacy of what we have.)
I'm sure there will be demands for fiber locals but we'd like push back 
for as long as possible to give time to explore and try out and 
hopefully prove better alternatives.

-Alan


More information about the loom-dev mailing list