On Mon, Jun 18, 2018 at 10:21 AM, Tony Printezis <tprinte...@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 | tprinte...@twitter.com > > > On June 18, 2018 at 10:13:02 AM, Martin Buchholz (marti...@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; > } > > > > >