我可以访问为线程池线程提交任务的线程(并且是 运行)吗?
Can I get an access to the thread which submitted task (and is running) for the thread of threadpool?
我想在MyThreadPoolExecutor
中覆盖ThreadPoolExecutor
的protected void beforeExecute(Thread t, Runnable r) { }
,我想知道哪个线程提交了这个(t
)线程的任务要去运行?我想将任务提交线程的 threadLocals 复制到将要 运行 此任务的线程 (t
)(在线程池中)。
我相信你可以在 runnable 中做这样的事情来获取正在执行的线程 ID。
private class MyTask implements Runnable {
public void run() {
long threadId = Thread.currentThread().getId();
logger.debug("Thread # " + threadId + " is doing this task");
}
如果你想尝试让线程池在 ThreadLocal 中执行线程更棘手,最好的方法是在你的 runnable class 中获取对 ThreadLocal 的访问权限。
我也在一个站点上阅读了这篇文章,我认为您可能需要重新考虑使用本地线程的自定义线程池的方法。
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.
因此,我们的 ThreadLocal 将在不同的 userIds 之间共享。这就是为什么我们不应该将 TheadLocal 与 ExecutorService 一起使用。仅当我们完全控制哪个线程将选择要执行的可运行操作时才应使用它。
我做到了
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);
}
}
我想在MyThreadPoolExecutor
中覆盖ThreadPoolExecutor
的protected void beforeExecute(Thread t, Runnable r) { }
,我想知道哪个线程提交了这个(t
)线程的任务要去运行?我想将任务提交线程的 threadLocals 复制到将要 运行 此任务的线程 (t
)(在线程池中)。
我相信你可以在 runnable 中做这样的事情来获取正在执行的线程 ID。
private class MyTask implements Runnable {
public void run() {
long threadId = Thread.currentThread().getId();
logger.debug("Thread # " + threadId + " is doing this task");
}
如果你想尝试让线程池在 ThreadLocal 中执行线程更棘手,最好的方法是在你的 runnable class 中获取对 ThreadLocal 的访问权限。
我也在一个站点上阅读了这篇文章,我认为您可能需要重新考虑使用本地线程的自定义线程池的方法。
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.
因此,我们的 ThreadLocal 将在不同的 userIds 之间共享。这就是为什么我们不应该将 TheadLocal 与 ExecutorService 一起使用。仅当我们完全控制哪个线程将选择要执行的可运行操作时才应使用它。
我做到了
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);
}
}