Recently I have been working on some code in which I was using ThreadLocal variables. This give me possibility to chew over the ThreadLocal variables concept again. The basic idea of this approach is quite simple. Every thread has its own copy of a ThreadLocalMap. When you ask for the value of the ThreadLocal variable it will search for this value in the ThreadLocalMap variable instance of the current thread.

When you are game to make a ThreadLocal variable inheritable between threads you can achieve this using the InheritableThreadLocal class. This implementation makes sure that the child thread will receive values from its parent ( on child thread creation) .

When I was playing around with my code based on a ThreadLocal variable I started to think about possible drawbacks. At first glance everything looked great but then the ExecutorService reared its head.

Code:


ExecutorService executor = Executors.newSingleThreadExecutor();

InheritableThreadLocal value = new InheritableThreadLocal<>();
value.set(1);

print(value); // main=1
executor.execute(()->print(value)); // pool-thread-1=1

value.set(2);
print(value); // main=2
executor.execute(() -> print(value)); // pool-thread-1=1 !?!

private static void print(ThreadLocal value) {
System.out.println(Thread.currentThread().getName() + "="+ value.get());
}

Console output:

main=1
main=2
pool-1-thread-1=1
pool-1-thread-1=1

What happened? The answer is quite simple.

  • The thread of the ExecutorService was initialized on the first call of the execute method.
  • Then the second call to the execute method reused the thread which was created in the first call.

A quick look into the implementation of the ExecutorService confirms that it is not working as I would like it to. It does not deal with ThreadLocals out-of-box.
I started to think about the easiest and fastest solution for the ExecutorService. Into my mind came the Spring Framework with their SecurityContext. I’m sure that they have faced the same problem with the SecurityContext in @Async calls. So probably they have invented something. After a few minutes I found the DelegatingSecurityContextExecutor class. In this class you will find inspiration for how you could build your own ExecutorServices or wrapped Runnable which deals with ThreadLocal variables.

Have a nice time digging into the details of the Spring approach!