RFR: JDK-8202788: Explicitly reclaim cached thread-local direct buffers at thread exit

Martin Buchholz martinrb at google.com
Mon Jun 18 17:53:26 UTC 2018


On Mon, Jun 18, 2018 at 10:21 AM, Tony Printezis <tprintezis at twitter.com>
wrote:

> Martin,
>
> You are forgiven. :-)
>
> So, the (valid, I think) issue with getIfPresent(), as originally proposed
> by Peter, was that if get() was overridden in the subclass to somehow
> transform the returned value, getIfPresent() wouldn’t apply the same
> transformation.
>
> Doesn’t your compute() method have essentially the same issue? Apart from
> that, I personally like this proposal as I agree: one look-up is always
> better than two.
>
>
A non-prototype implementation would delegate compute into ThreadLocalMap
itself, where there is no risk of overriding.


> Tony
>
>
> —————
> Tony Printezis | @TonyPrintezis | tprintezis at twitter.com
>
>
> On June 18, 2018 at 10:13:02 AM, Martin Buchholz (martinrb at google.com)
> wrote:
>
> I'm ignoring the direct buffers problem (sorry Tony) and wearing my
> ReentrantReadWriteLock hat.  I still like the idea of adding
> ThreadLocal.compute(Function remappingFunction) and perhaps other such
> map-inspired methods. RRWL wouldn't benefit much, since it already tries to
> minimize use of ThreadLocal, but it would at least allow get() and remove()
> to be coalesced on read-unlock.
>
> RRWL never changes from one non-null value to another, it only switches
> between absent and present.  I'd like to avoid the two lookups due to get
> and remove.  Here's a prototype that does not yet help RRWL, but helps
> callers switching between non-null values, and could probably be extended
> via surgery to ThreadLocalMap:
>
>     public T compute(
>             java.util.function.Function<? super T,? extends T>
> remappingFunction) {
>         final Thread currentThread = Thread.currentThread();
>         final ThreadLocalMap map = getMap(currentThread);
>         final ThreadLocalMap.Entry e = (map == null)
>             ? null
>             : map.getEntry(this);
>         final T oldValue = (e == null) ? null : (T)e.value;
>         final T newValue = remappingFunction.apply(oldValue);
>         if (newValue == null) {
>             if (oldValue != null) {
>                 map.remove(this);
>             }
>         } else if (e != null) {
>             e.value = newValue;
>         } else if (map != null) {
>             map.set(this, newValue);
>         } else {
>             createMap(currentThread, newValue);
>         }
>         return newValue;
>     }
>
>
>
>
>


More information about the core-libs-dev mailing list