I was going through the concept of ThreadLocals on the below blog :
https://www.baeldung.com/java-threadlocal
It says that "Do not use ThreadLocal with ExecutorService"
It illustrates below example for using ThreadLocals.
public class ThreadLocalWithUserContext implements Runnable {
private static ThreadLocal<Context> userContext
= new ThreadLocal<>();
private Integer userId;
private UserRepository userRepository = new UserRepository();
@Override
public void run() {
String userName = userRepository.getUserNameForUserId(userId);
userContext.set(new Context(userName));
System.out.println("thread context for given userId: "
+ userId + " is: " + userContext.get());
}
// standard constructor
}
At the End of the post it mentions that :
If we want to use an ExecutorService and submit a Runnable to it, using ThreadLocal will yield non-deterministic results – because we do not have a guarantee that every Runnable action for a given userId will be handled by the same thread every time it is executed.
Because of that, our ThreadLocal will be shared among different userIds. That’s why we should not use a TheadLocal together with ExecutorService. It should only be used when we have full control over which thread will pick which runnable action to execute.
This explanation was a bouncer to me. I tried to do some research online for this point specifically but I could not get much help, can some expert please elaborate on the above explanation? Is it authors view or a real Threat?
The point of that caution is that multiple runs of your Runnable
may execute on different threads. An executor service can be backed by a single thread but it may just as well be backed by a pool of threads. On subsequent executions of your Runnable
, a different thread will be accessing a different ThreadLocal
.
So you certainly can use ThreadLocal
within a single run of the Runnable
. But it is not likely to be useful, as generally the purpose of a ThreadLocal
is to hold a value for a while. In contrast, a Runnable
should generally be short-lived.
So, no, generally it does not make sense to use a ThreadLocal
with a thread pool.