Как инициализировать объекты 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);