Как инициализировать объекты ThreadLocal в Java

У меня возникла проблема, когда я создаю ThreadLocal и инициализирую его новым ThreadLocal. Проблема в том, что я действительно концептуально хочу, чтобы постоянный список продолжал жизнь потока, но я не знаю, есть ли способ инициализировать что-то в потоке в Java.

например. я хочу что-то вроде:

ThreadLocal static {
  myThreadLocalVariable.set(new ArrayList<Whatever>());
}

Чтобы он инициализировал его для каждого потока. Я знаю, что могу это сделать:

private static Whatever getMyVariable() {
  Whatever w = myThreadLocalVariable.get();
  if(w == null) {
    w = new ArrayList<Whatever>();
    myThreadLocalVariable.set(w);
  }
  return w; 
}

но мне бы действительно не нужно было проверять это каждый раз, когда он использовался. Я могу здесь что-нибудь улучшить?

Ответы

Ответ 1

Вы просто переопределите метод initialValue():

private static ThreadLocal<List<String>> myThreadLocal =
    new ThreadLocal<List<String>>() {
        @Override public List<String> initialValue() {
            return new ArrayList<String>();
        }
    };

Ответ 2

Ваше решение в порядке. Небольшое упрощение:

private static Whatever getMyVariable() 
{
    Whatever w = myThreadLocalVariable.get();
    if(w == null) 
        myThreadLocalVariable.set(w=new Whatever());
    return w; 
} 

В Java 8 мы можем сделать:

ThreadLocal<ArrayList<Whatever>> myThreadLocal = ThreadLocal.withInitial(ArrayList::new);

который использует функциональный интерфейс Supplier<T>.

Ответ 3

Принятый ответ устарел в JDK8. Это лучший способ с тех пор:

private static final ThreadLocal<List<Foo>> A_LIST = 
    ThreadLocal.withInitial(ArrayList::new);