Quick Introduction to ThreadLocal

Introduction

ThreadLocal variables are usually private static fields in classes and maintain its state inside a thread and generate unique identifiers local to each thread. This meas that every time a different thread accesses the same instance, a new ThreadLocal variable is created. Therefore, information saved in a ThreadLocal can only be accessed by a single thread for a particular instance.

Lifecycle

ThreadLocal variables are created when a thread accesses an instance, and all the copies of ThreadLocal variables are ready to be garbage collected when the thread goes away, unless there are other references to the ThreadLocal variables.

If a class is setting a ThreadLocal value in a static block, only the thread that initializes the class will be able to retrieve the value, since static blocks are only call during class initialization.

public class MyThreadLocalManager {
    private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    static {
        threadLocal.set(10);
    }
    public Integer getInteger() {
        return threadLocal.get();
    }
    public void setInteger(Integer integer) {
        threadLocal.set(integer);
    }
}

Therefore, if a thread accesses the instance of the previous class, which was originally initialized by another thread, and calls getInteger(), it will return null.

MyThreadLocalManager myThreadLocalManager = new MyThreadLocalManager();
System.out.println(myThreadLocalManager.getInteger()); // prints 10
new Thread("thread-2") {
    @Override
    public void run() {
        System.out.println(myThreadLocalManager.getInteger()); // prints null
    }
}.start();

In order to initialize our ThreadLocal with a value, we can use the new Java 8 withInitial()

static {
    threadLocal = ThreadLocal.withInitial(() -> 10);
}

Now the output will be “10” for every thread that uses the MyThreadLocalManager instance.

Operations

Use Cases

Caveats

ThreadLocal can cause memory leaks if it is not used safely. In web applications thread workers are provided by web servers like Tomcat or Jetty, and they maintain a thread pool to serve HTTP requests. Therefore, if a request creates a ThreadLocal and it is not removed before the response is returned, a copy of the object which contains the ThreadLocal will remain with a worker Thread in the web server, and since lifespan of a worker thread is longer than the webapp itself, it will prevent the object from being garbage collected. So always remember to remove ThreadLocal variables when they are not useful anymore.