虚拟线程、执行器和执行器钩子方法

问题描述 投票:0回答:1

我正在尝试弄清楚如何使用虚拟线程,但仍然使用

ThreadPoolExecutor#beforeExecute

我的旧代码只是扩展了

ThreadPoolExecutor
,但它的构造函数采用核心/最大池大小、队列,我认为你不应该在虚拟线程中使用或需要这些东西。

有没有办法通过虚拟线程来享受

beforeExecute

java multithreading executorservice virtual-threads
1个回答
0
投票

您可以滥用

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));

© www.soinside.com 2019 - 2024. All rights reserved.