I ran into the same problem, and seeing the answers here, I decided to use a hybrid approach:
public class PersistentThreadLocal<T> extends ThreadLocal<T> { final Map<Thread, T> allValues; final Supplier<? extends T> valueGetter; public PersistentThreadLocal(Supplier<? extends T> initialValue) { this(0, initialValue); } public PersistentThreadLocal(int numThreads, Supplier<? extends T> initialValue) { allValues = Collections.synchronizedMap( numThreads > 0 ? new WeakHashMap<>(numThreads) : new WeakHashMap<>() ); valueGetter = initialValue; } @Override protected T initialValue() { T value = valueGetter != null ? valueGetter.get() : super.initialValue(); allValues.put(Thread.currentThread(), value); return value; } @Override public void set(T value) { super.set(value); allValues.put(Thread.currentThread(), value); } @Override public void remove() { super.remove(); allValues.remove(Thread.currentThread()); } public Collection<T> getAll() { return allValues.values(); } public void clear() { allValues.clear(); } }
EDIT: if you plan to use this with ThreadPoolExecutor, change WeakHashMap to a regular HashMap , otherwise strange things will happen!
Sina Madani Nov 13 '17 at 15:28 2017-11-13 15:28
source share