package io.pcp.parfait.timing;
import java.util.Collections;
import java.util.Map;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
public interface ThreadValue<T> {
T get();
boolean canRetrieveAcrossThreads();
T getForThread(Thread thread);
Map<Thread, T> asMap();
public static class ThreadLocalMap<T> implements ThreadValue<T> {
protected final ThreadLocal<? extends T> threadLocal;
public ThreadLocalMap(ThreadLocal<? extends T> threadLocal) {
this.threadLocal = threadLocal;
}
@Override
public final boolean canRetrieveAcrossThreads() {
return false;
}
@Override
public final T get() {
return threadLocal.get();
}
@Override
public final T getForThread(Thread thread) {
if (thread == Thread.currentThread()) {
return threadLocal.get();
}
return null;
}
@Override
public final Map<Thread, T> asMap() {
return Collections.emptyMap();
}
}
public static class WeakReferenceThreadMap<T> implements ThreadValue<T> {
protected final LoadingCache<Thread, T> loadingCache = CacheBuilder.newBuilder().weakKeys().build(new CacheLoader<Thread, T>() {
@Override
public T load(Thread thread) throws Exception {
return initialValue();
}
});
protected T initialValue() {
return null;
}
@Override
public final boolean canRetrieveAcrossThreads() {
return true;
}
@Override
public final T get() {
return loadingCache.getUnchecked(Thread.currentThread());
}
@Override
public final T getForThread(Thread thread) {
return loadingCache.getUnchecked(thread);
}
@Override
public final Map<Thread, T> asMap() {
return loadingCache.asMap();
}
}
}