I am trying to use both InheritableThreadLocal
and a ThreadPoolExecutor
.
This breaks down because ThreadPoolExecutor
reuses threads for each pool (it is a pool, after all), meaning the InheritableThreadLocal
doesn't work as expected. Now the problem seems obvious to me, but it was particularly snarly to track down.
I use InheritableThreadLocal
so that each of several top-level processes has its own database connection for itself and any sub-processes it spawns. I don't just use one shared connection pool because each top-level process will do a lot of multi-step work with its connection before committing to the database and/or preparing a lot of PreparedStatements that are used over and over.
I use a shared ThreadPoolExecutor
between these top-level processes because there are certain behaviors that need to be gated. e.g. Even though I might have 4 top-level processes running, I can only have any one process writing to the database at a time (or the system needs to gate on some other shared resource). So I'll have the top-level process create a Runnable
and send it to the shared ThreadPoolExecutor
to make sure that no more than one (or two or three as the case may be) are running at the same time across the entire system.
The problem is that because the ThreadPoolExecutor
reuses its threads for the pools, the InheritableThreadLocal
is picking up the original value that was run in that pool rather than the value that was in the top-level process which sent the Runnable to the ThreadPoolExecutor
.
Is there any way to force the worker pool in the ThreadPoolExecutor
to use the InheritableThreadLocal
value that was in the context of the process which created the Runnable rather than in the context of the reused thread pool?
Alternatively, is there any implementation of ThreadPoolExecutor
that creates a new thread each time it starts a new Runnable? For my purposes I only care about gating the number of simultaneously running threads to a fixed size.
Is there any other solution or suggestion people have for me to accomplish what I've described above?
(While I realize I could solve the problem by passing around the database connection from class to class to subthread to subthread like some kind of community bicycle, I'd like to avoid this.)
There is a previous question on StackOverflow, InheritableThreadLocal and thread pools, that addresses this issue as well. However, the solution to that problem seems to be that it's a poor use case for InheritableThreadLocal, which I do not think applies to my situation.
Thanks for any ideas.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…