web-dev-qa-db-ja.com

JavaでThreadLocalオブジェクトを初期化する方法

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; 
}

でも、実際に使用するたびにチェックする必要はありません。ここでもっと良いことはありますか?

23
B T

initialValue()メソッドをオーバーライドするだけです。

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

あなたの解決策は大丈夫です。少し単純化:

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> 機能インターフェース。

17
ZhongYu

受け入れられた回答はJDK8では古くなっています。それ以来、これが最善の方法です。

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