我正在尝试弄清楚如何使用虚拟线程,但仍然使用
ThreadPoolExecutor#beforeExecute
。
我的旧代码只是扩展了
ThreadPoolExecutor
,但它的构造函数采用核心/最大池大小、队列,我认为你不应该在虚拟线程中使用或需要这些东西。
有没有办法通过虚拟线程来享受
beforeExecute
?
您可以滥用
ThreadPoolExecutor
为每个任务创建一个新的虚拟线程,而无需实际的池,例如
public class PseudoThreadPoolExecutor extends ThreadPoolExecutor {
public PseudoThreadPoolExecutor() {
super(0, Integer.MAX_VALUE, 0L, TimeUnit.NANOSECONDS,
new SynchronousQueue<>(), Thread.ofVirtual().factory());
}
public PseudoThreadPoolExecutor(RejectedExecutionHandler handler) {
super(0, Integer.MAX_VALUE, 0L, TimeUnit.NANOSECONDS,
new SynchronousQueue<>(), Thread.ofVirtual().factory(), handler);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
System.out.println("PseudoThreadPoolExecutor.beforeExecute() "
+ r + " on " + t);
}
}
但是,当您想要的只是在每个任务之前执行一个钩子时,就不需要这种方法了:
public static ExecutorService newVirtualThreadPerTaskExecutor(
BiConsumer<Thread, Runnable> before) {
ThreadFactory base = Thread.ofVirtual().factory();
ThreadFactory withBefore = r -> base.newThread(() -> {
before.accept(Thread.currentThread(), r);
r.run();
});
return Executors.newThreadPerTaskExecutor(withBefore);
}
ExecutorService es = newVirtualThreadPerTaskExecutor((t,r) ->
System.out.println("VirtualThreadPerTaskExecutor.beforeExecute() "
+ r + " on " + t));