Don't subclass ThreadLocal.

This attempts to address issue 402, wherein subclassing ThreadLocal is pinning a reference to a class, which transitively pins the entire application in containers like Tomcat.
This commit is contained in:
Jesse Wilson 2012-10-23 02:41:34 +00:00
parent 22c835f2bc
commit 1e18dce002

View File

@ -111,11 +111,7 @@ public final class Gson {
* The proxy is wired up once the initial adapter has been created. * The proxy is wired up once the initial adapter has been created.
*/ */
private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls
= new ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>() { = new ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>();
@Override protected Map<TypeToken<?>, FutureTypeAdapter<?>> initialValue() {
return new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
}
};
private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache
= Collections.synchronizedMap(new HashMap<TypeToken<?>, TypeAdapter<?>>()); = Collections.synchronizedMap(new HashMap<TypeToken<?>, TypeAdapter<?>>());
@ -343,6 +339,11 @@ public final class Gson {
} }
Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get(); Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
if (threadCalls == null) {
threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
calls.set(threadCalls);
}
// the key and value type parameters always agree // the key and value type parameters always agree
FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type); FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
if (ongoingCall != null) { if (ongoingCall != null) {