org.terracotta.statistics.util.VicariousThreadLocal Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/**
* Copyright 2006 Thomas Hawtin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terracotta.statistics.util;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
/**
* A drop-in replacement {@code ThreadLocal} implementation that does not leak
* when thread-local values reference the {@code ThreadLocal} object.
* The code is optimised to cope with frequently changing values.
*
* In comparison to plain {@code ThreadLocal}, this implementation:
* - from the point of view of a single thread,
* each thread-local
* {code #get} requires access to four objects instead of two
*
- is fractionally slower in terms of CPU cycles for {code #get}
*
- uses around twice the memory for each thead-local value
*
- uses around four times the memory for each {@code ThreadLocal}
*
- may release thread-local values for garbage collection more promptly
*
*/
public class VicariousThreadLocal extends ThreadLocal {
/**
* Maps a unique WeakReference onto each Thread.
*/
private static final ThreadLocal> weakThread =
new ThreadLocal>();
/**
* Returns a unique object representing the current thread.
* Although we use a weak-reference to the thread,
* we could use practically anything
* that does not reference our class-loader.
*/
static WeakReference currentThreadRef() {
WeakReference ref = weakThread.get();
if (ref == null) {
ref = new WeakReference(Thread.currentThread());
weakThread.set(ref);
}
return ref;
}
/**
* Object representing an uninitialised value.
*/
private static final Object UNINITIALISED = new Object();
/**
* Actual ThreadLocal implementation object.
*/
private final ThreadLocal> local =
new ThreadLocal>();
/**
* Maintains a strong reference to value for each thread,
* so long as the Thread has not been collected.
* Note, alive Threads strongly references the WeakReference<Thread>
* through weakThread.
*/
private volatile Holder strongRefs;
/**
* Compare-and-set of {@link #strongRefs}.
*/
private static final AtomicReferenceFieldUpdater strongRefsUpdater =
AtomicReferenceFieldUpdater.newUpdater(VicariousThreadLocal.class, Holder.class, "strongRefs");
/**
* Queue of Holders belonging to exited threads.
*/
private final ReferenceQueue