Hello, Has it been discussed whether or not CarrierThreadLocal (currently in JDK.internal.misc) could/should be public API? I think it may be useful.
The introduction of virtual threads has (more or less) silently changed the semantics of ThreadLocal somewhat: before vthreads, ThreadLocal used to always be local to platform threads (because that was the only kind of thread that existed). With vthreads, ThreadLocal is now local to the VirtualThread, if the code happens to run in a vthread, or otherwise local to the PlatformThread. I think in most cases this may be the intended behavior. Although I might point out that this can result in an enormous churn of ThreadLocal instances. I also realize that many typical use-cases are better served by the new ScopeLocal and that is great. However, there are genuine use-cases where one might consciously want a carrier-thread-local: We (at Datadog) have this situation: we want to associate a context (think OTEL span context) with (platform) threads, on the native side. And we need to access that context from Java. And we do so by wrapping that native context in a DirectByteBuffer. And because those accesses are rather frequent, we need to preserve the DBB and stick it in a ThreadLocal. That used to be the right thing to do - the native context is also thread-local after all. Now, with virtual threads, that ThreadLocal suddenly becomes local to the vthread. Which means that the DBB points to the native context of the first carrier thread that the vthread accessed. As soon as the vthread gets unmounted and remounted to a different carrier, it points to the wrong context. And even worse, when the original carrier thread ends, it points to any unallocated or reallocated memory and cause crashes and/or native heap corruptions. We have seen all of those symptoms. The right thing to do is to use CarrierThreadLocal to associate the DBB with the correct platform thread. I realize that this might be a rather niche use-case, but I would think that there are more situations where storing information local to carrier threads might be useful. So the question: would it be feasible to make CarrierThreadLocal a public API? Or is that absolutely not possible, and should we rather stick with using it via reflection and hope for the best? I suppose an alternative would be to expose getCarrierThread() or similar from virtual threads, but that would be less elegant (at least for our use). WDYT? Roman
