Наивно я ожидал, что ThreadLocal будет своего рода WeakHashMap Thread для типа значения. Поэтому я был немного озадачен, когда узнал, что значения ThreadLocal на самом деле сохранено на карте в треде. Почему это было сделано именно так? Я ожидаю, что утечек ресурсов, связанных с ThreadLocal, не будет, если значения сохраняются в самом ThreadLocal.
Уточнение: я думал о чем-то вроде
public class AlternativeThreadLocal<T> {
private final Map<Thread, T> values =
Collections.synchronizedMap(new WeakHashMap<Thread, T>());
public void set(T value) { values.put(Thread.currentThread(), value); }
public T get() { return values.get(Thread.currentThread());}
}
Насколько я вижу, это предотвратило бы странную проблему, заключающуюся в том, что ни ThreadLocal, ни его оставшиеся значения никогда не могут быть собраны мусором до тех пор, пока Thread не умрет, если значение каким-то образом сильно ссылается на сам ThreadLocal. (Возможно, самая коварная форма этого происходит, когда ThreadLocal является статической переменной в классе, на который ссылается значение. Теперь у вас есть большая утечка ресурсов при повторных развертываниях на серверах приложений, поскольку ни объекты, ни их классы не могут быть собраны.)