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