How to initialize ThreadLocal objects in Java

2019-01-26 04:07发布

I'm having an issue where I'm creating a ThreadLocal and initializing it with new ThreadLocal . The problem is, I really conceptually just want a persistent list that lasts the life of the thread, but I don't know if there's a way to initialize something per-thread in Java.

E.g. what I want is something like:

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

So that it initializes it for every thread. I know I can do this:

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

but I'd really rather not have to do a check on that every time it's used. Is there anything better I can do here?

3条回答
【Aperson】
2楼-- · 2019-01-26 04:36

You just override the initialValue() method:

private static ThreadLocal<List<String>> myThreadLocal =
    new ThreadLocal<List<String>>() {
        @Override public List<String> initialValue() {
            return new ArrayList<String>();
        }
    };
查看更多
狗以群分
3楼-- · 2019-01-26 04:36

Your solution is fine. A little simplification:

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

In Java 8, we are able to do:

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

which uses the Supplier<T> functional interface.

查看更多
冷血范
4楼-- · 2019-01-26 04:51

The accepted answer is outdated in JDK8. This is the best way since then:

private static final ThreadLocal<List<Foo>> A_LIST = 
    ThreadLocal.withInitial(ArrayList::new);
查看更多
登录 后发表回答