[External] : Re: Thread-local successor for object pooling

Ron Pressler ron.pressler at oracle.com
Thu Nov 3 20:43:30 UTC 2022


I’d like to explain what the problem is, because I think it’s the most important thing. The mechanism of associating data with the thread is not the main issue. The problem is *what* data is associated with a thread. Associating context-specific data, i.e. task-specific data with a thread is fine. The problem is associating data with a thread that is *not* task-specific, i.e. data that is to be shared among multiple tasks.

The solution to that problem is not offering an alternative mechanism for associating data with a thread, but getting people to stop doing that altogether: data that needs to be shared among multiple tasks should *not* be associated with a thread. Others have suggested using pools based on concurrent data structures, and those would work (we might someday offer more efficient pools, but those still would not be alternatives to thread locals in the sense that they will not associate data with threads).

Similarly, disabling thread locals is not a problem here. Whether thread locals are disabled or not, if code associates task-shared data with a thread, the application will misbehave (by introducing large footprint and initialisation overheads) when every task has its own thread, even with thread locals enabled. Again, the solution is to stop doing that.

On the other hand, associating *task-specific* data with a thread is fine, whether using TLs (which aren’t going away) or more efficient and correct alternatives like ScopedValues. The option to disallow thread locals is intended for specialised use-cases that *want* to forbid TLs, and TLs are obviously allowed by default.

In short: TLs are not a problem. The problem is associating shared caches with a thread, because threads are less likely to be shared. The alternative is to not do that (and rely on object pools where they’re found to actually help).

— Ron

On 2 Nov 2022, at 14:38, Volkan Yazıcı <volkan at yazi.ci<mailto:volkan at yazi.ci>> wrote:

Is it safe to assume that the disableThreadLocals toggle will only be released along with a decent alternative (e.g., ScopedValues)? Otherwise, libraries relying on TLs will simply not work due to the thrown UnsupportedOperationException. Put another way, Log4j can replace TLs that serve object pooling purposes with something else, today; though for TLs that are used to pass context, disableThreadLocals=true will simply render them broken without a solution.

On Wed, Nov 2, 2022 at 11:30 AM Ron Pressler <ron.pressler at oracle.com<mailto:ron.pressler at oracle.com>> wrote:
There is no difference in capabilities or behaviour between virtual threads and platform threads when it comes to ThreadLocals. It’s just that because some particular uses of TLs make an implicit assumption about threads being shared and few in number, assumptions that are usually true for platform threads and usually untrue for virtual threads, we’ve added the possibility of disabling ThreadLocals for any kind of thread. By default, all threads allow TLs, and so running old code on virtual threads will work as before.

Just to be clear, there is nothing *fundamentally* wrong about TLs, nor their use in virtual threads. It’s just that thread usage patterns have led to *some* TL usage patterns that would be problematic with common virtual thread usage patterns. Many if not most uses of TLs — those that associate domain context with a task — are fine with virtual threads (although ScopedValues are much better). There is no need to deprecate ThreadLocal nor a plan to ever do so.

— Ron

On 2 Nov 2022, at 00:03, Carter Kozak <ckozak at ckozak.net<mailto:ckozak at ckozak.net>> wrote:

> That's right but not specific to virtual threads. It is also possible to
> create platform threads that do not support TLs. This is something that
> we need a lot more feedback on before deciding if that part of the API
> should be made permanent.

This is an interesting point. I'm not sure I understand why the introduction of virtual threads is the best place to make the ThreadLocal language feature configurable, but I'd appreciate additional context.
The JEP describes the motivation for the dynamic configuration of ThreadLocals, as well as an alternative (jep-429 scoped values), however the behavior seems (to an outsider) to oppose the higher-level design of virtual threads which are meant to be otherwise a drop-in replacement for platform threads. I'd much rather fail predictably (or in a way the compiler can warn me about) rather than when a legacy function compiled with jdk1.5 executes on a particular type of thread.
Given that using virtual threads is going to be a decision that happens in isolation from code that may use ThreadLocals, ideally we could introduce alternatives to ThreadLocal safely in an LTS before making ThreadLocal throw. Then, we could add the configuration point to disable ThreadLocals (on all types of thread?) and/or for potentially greater consistency, deprecate ThreadLocal for removal.

> It would be interesting to know if log4j has done any recent evaluation
> with newer JDK releases and GCs to see their object pooling has a
> positive or negative benefit.

Yes, it's complicated. Performance has certainly changed over time with JDK releases and the benefits are use-case dependent. The primary benefit is isolation (lack of impact on GC, which itself may impact seemingly unrelated components).

Thanks,
Carter Kozak


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20221103/415c3fe7/attachment-0001.htm>


More information about the loom-dev mailing list