我有一个
AsyncTaskExecutor
的自定义实现,它使用虚拟线程来运行任务。我在这里使用 ThreadFactory
,因为我需要包装任务以执行横切关注点。
由于 VT 是守护线程,我认为即使应用程序停止后,这些线程也会在后台继续运行一段时间。
有没有办法确保在应用程序停止之前清理使用
AsyncTaskExecutor
创建的所有虚拟线程?
异步任务执行器:
public class VirtualThreadTaskExecutor implements AsyncTaskExecutor {
private final ThreadFactory threadFactory;
public VirtualThreadTaskExecutor() {
this.threadFactory = Thread.ofVirtual().name("my-app-virtual-thread-", 0).factory();
}
@Override
public void execute(@NotNull Runnable task) {
var wrapped = MyTaskWrapper.wrap(task);
threadFactory.newThread(wrapped).start();
}
@Override
@Deprecated
public void execute(@NotNull Runnable task, long startTimeout) {
var future = new FutureTask<>(task, null);
execute(future);
}
@NotNull
@Override
public Future<?> submit(@NotNull Runnable task) {
var future = new FutureTask<>(task, null);
execute(future);
return future;
}
@NotNull
@Override
public <T> Future <T> submit(@NotNull Callable <T> task) {
var future = new FutureTask<>(task);
execute(future);
return future;
}
}
豆:
@Bean
public AsyncTaskExecutor virtualThreadExecutor() {
return new VirtualThreadTaskExecutor();
}
我相信另一种选择是使用
SimpleAsyncTaskExecutor
和 setTaskTerminationTimeout
,当调用 close()
方法时会调用它们。
您可以使用
VirtualThreadTaskExecutor
来处理您的
TaskDecorator
实现,同时使用虚拟线程与 wrap
,而不是定义自定义 SimpleAsyncTaskExecutor
setVirtualThreads
配置设置为 true
。 @Bean
看起来像:
@Bean
public AsyncTaskExecutor virtualThreadTaskExecutor() {
SimpleAsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor();
asyncTaskExecutor.setVirtualThreads(true); // virtual threads enabled
asyncTaskExecutor.setTaskDecorator(MyTaskWrapper::wrap); // your custom wrapper
asyncTaskExecutor.setThreadFactory(Thread.ofVirtual().name("my-app-virtual-thread-", 0).factory());
asyncTaskExecutor.setTaskTerminationTimeout(5000); // ensure wait for task termination
return asyncTaskExecutor;
}