I am trying to use both InheritableThreadLocal
and a ThreadPoolExecutor
.
This breaks down because ThreadPoolExecutor
reuses th
Why not just pass the current connection on to any sub-tasks spawned by the main task? maybe some sort of shared Context object?
using InheritedThreadLocal
is almost surely wrong. Probably you'd have not asked the question if you can fit that bizarre tool.
First and foremost it's horribly leak-prone and often the value(s) escapes in some totally strange threads.
As for the Runnable being associate w/ a context.
Override publicvoid execute(Runnable command)
of the ExecutorPool
and wrap the Runnable
withing some context carrying the value you want in the first place from the InheritedThreadLocal
.
The wrapping class shall look something like
class WrappedRunnable extends Runnable{
static final ThreadLocal<Ctx> context=new ThreadLocal<Ctx>();
final Runnable target;
final Ctx context;
WrappedRunnable(Ctx context, Runnable target){...}
public void run(){
ctx.set(context);
try{
target.run();
}finally{
ctx.set(null);//or ctx.remove()
}
}
}
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.
While truly bad from performance point of view, you can implement your own, basically you need only execute(Runnable task)
method for the Executor
that spawns new thread and starts it.
Instead of using a ThreadPoolExecutor to protect shared resources, why not use a java.util.concurrent.Semaphore
? The sub tasks you create would run to completion in their own threads, but only after having acquired a permit from the semaphore, and of course releasing the permit when done.
We had the same issue earlier and we solved this issue by writing ThreadLocalContextMigrator which basically copies the thread local context to the task that will be executed using a thread from the pool. The Task, while executing will collect more context info and upon completion of the task we copy it back.