我遇到了类似的问题,最终创建了一个 ForkListeningExecutorService,它包装了一个 ExecutorService(参见 here)。每当任务提交给执行程序或结束时,包装器都会向侦听器发送事件。然后,您可以使用侦听器在线程之间传递您想要的任何内容。这是 Listener 的样子:
/**
* Listener that will receive the events around task submission.
*
*/
public interface ExecutorServiceListener {
/**
* Will be called <b>before</b> any task is submitted to the service. This method will therefore run on the original "parent" thread.
*/
default void beforeTaskSubmission() {
// to be overridden by implementations
}
/**
* Will be called <b>after</b> a task is submitted to the service and <b>before</b> the actual execution starts. This method will therefore run on the new "child" thread.
*/
default void afterTaskSubmission() {
// to be overridden by implementations
}
/**
* Will be called <b>before</b> a submitted task ends no matter if an exception was thrown or not. This method will therefore run on the new "child" thread just before it's
* released.
*/
default void beforeTaskEnds() {
// to be overridden by implementations
}
}
因此,您可以简单地包装它(或任何其他 ExecutorService 实现),而不是扩展 ThreadPoolExecutor,并像这样在侦听器中传递状态:
public class ForkListeningExecutorServiceExample {
private static ThreadLocal<String> threadLocal = new ThreadLocal<>();
private static void printThreadMessage(final String message) {
System.out.println(message
+ ", current thread: " + Thread.currentThread().getName()
+ ", value from threadLocal: " + threadLocal.get());
}
public static void main(final String[] args) throws Exception {
threadLocal.set("MY_STATE");
final ExecutorService executorService = new ForkListeningExecutorService(
Executors.newCachedThreadPool(),
new ExecutorServiceListener() {
private String valueToShare;
@Override
public void beforeTaskSubmission() {
valueToShare = threadLocal.get();
printThreadMessage("The task is about to be submitted");
}
@Override
public void afterTaskSubmission() {
threadLocal.set(valueToShare);
printThreadMessage("The task has been submitted and will start now");
}
@Override
public void beforeTaskEnds() {
threadLocal.set(null);
printThreadMessage("The task has finished and thread will be released now");
}
});
executorService.submit(() -> {
printThreadMessage("The task is running now");
}).get();
printThreadMessage("We are back on the main thread");
}
}
输出如下所示:
The task is about to be submitted, current thread: main, value from threadLocal: MY_STATE
The task has been submitted and will start now, current thread: pool-1-thread-1, value from threadLocal: MY_STATE
The task is running now, current thread: pool-1-thread-1, value from threadLocal: MY_STATE
The task has finished and thread will be released now, current thread: pool-1-thread-1, value from threadLocal: null
We are back on the main thread, current thread: main, value from threadLocal: MY_STATE