Using InheritableThreadLocal with ThreadPoolExecutor — or — a ThreadPoolExecutor that doesn't reuse threads

一世执手 提交于 2019-11-28 09:47:15

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.

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.

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.

Why not just pass the current connection on to any sub-tasks spawned by the main task? maybe some sort of shared Context object?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!