我想覆盖protected void beforeExecute(Thread t, Runnable r) { }
中ThreadPoolExecutor
中MyThreadPoolExecutor
的{{1}},在那里我想知道哪个线程已提交了该(t
)线程要执行的任务跑?我想将提交线程的threadLocals的任务复制到将要运行此任务的线程({t
)中(在threadPool中)。
答案 0 :(得分:1)
我设法做到了
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
}
@Override
public Future<?> submit(Runnable task) {
// get the threadLocal from current thread which is task submitting thread
boolean threadLocalValueFromParentThread = ThreadLocalsUtils.getThreadLocalValueForThisThread.get();
Runnable wrappedTask = () -> {
try {
// set value of task submitting thread's value in whichever thread gets this runnable.
ThreadLocalsUtils.setThreadLocalValueForThisThread(threadLocalValueFromParentThread);
task.run();
} finally {
ThreadLocalsUtils.setThreadLocalValueForThisThread(false);
}
};
return super.submit(wrappedTask);
}
}
答案 1 :(得分:0)
我相信您可以在runnable中执行类似的操作,以获取要在其中执行的线程ID。
private class MyTask implements Runnable {
public void run() {
long threadId = Thread.currentThread().getId();
logger.debug("Thread # " + threadId + " is doing this task");
}
如果要尝试让线程池在ThreadLocal中执行线程更为棘手,最好的方法是在可运行类中访问ThreadLocal。
我也在网站上读过这篇文章,并认为您可能想重新考虑使用本地线程的自定义线程池的方法。
如果我们要使用ExecutorService并向其提交Runnable,则使用ThreadLocal会产生不确定的结果-因为我们不能保证每次给定userId的每个Runnable操作都会由同一线程处理它被执行。
因此,我们的ThreadLocal将在不同的userId之间共享。这就是为什么我们不应该将TheadLocal与ExecutorService一起使用。仅当我们完全控制哪个线程将选择要执行的可运行操作时,才应使用它。