【问题标题】:Force re-use of thread by CompletableFutureCompletableFuture 强制重用线程
【发布时间】:2019-02-07 00:50:57
【问题描述】:

我正在批判性地使用:

 CompletableFuture
  .delayedExecutor(1, TimeUnit.MILLISECONDS).execute(() -> {});

从我在线阅读的内容来看,每次通话都使用一个新线程是很常见的。我想知道是否有办法重用线程而不是创建新线程?

更新

我不清楚 - 我想使用 CompletableFuture,但我希望 CompletableFuture 重用某个线程,而不是管理它自己的线程。

我看到了这个问题: CompletableFuture reuse thread from pool

但它建议使用环境变量 - 我想知道是否有办法以编程方式执行此操作。

【问题讨论】:

  • 你有多少个处理器?
  • 你为什么不使用ExecutorService 来发送它?
  • 我可以使用 ExecutorService 来调度,但我不知道我可以这样做,你能添加一个答案来说明如何?
  • @shmosel 8 个处理器 .. 这段代码将在许多不同的机器上运行,而不仅仅是我家里的笔记本电脑或其他任何机器
  • 那么它应该使用开箱即用的线程池。

标签: java multithreading executorservice threadpoolexecutor completable-future


【解决方案1】:

根据我在网上阅读的内容,每次调用都使用一个新线程是很常见的。

(1) 仅当机器不支持并行性或您通过将系统属性java.util.concurrent.ForkJoinPool.common.parallelism 设置为01 使其不支持时才会出现这种情况。

8 个处理器

(2) 如果机器确实支持并行,则使用ForkJoinPool.commonPool(),并且并行级别设置为可用处理器的数量(可以由Runtime#availableProcessors 确定)。

在具有 8 个处理器的场景中,可能会创建 7-8 个线程来服务于公共 ForkJoinPool

我想使用CompletableFuture,但我希望CompletableFuture重用某个线程,而不是管理自己的线程。

DelayedExecutor 只是将任务提交给底层Executor,它要么是ThreadPerTaskExecutor (1) 要么是ForkJoinPool (2)。

幸运的是,您可以手动指定 ExecutorDelayedExecutor 将使用它来委派任务。

Executor delayedExecutor = 
     CompletableFuture.delayedExecutor(1, TimeUnit.MILLISECONDS, executor);

它让我们回到your previous question,我在pointed out 那里可以用ThreadFactory 定义Executor

Executor executor = Executors.newCachedThreadPool(YourThreadClass::new);

【讨论】:

    【解决方案2】:

    Executor为每组任务创建新线程

    通常使用 Executor 而不是显式创建线程。例如,不是为一组任务中的每一个调用 new Thread(new(RunnableTask())).start(),您可以使用:对于一组任务中的每一个

    Executor executor = anExecutor;
    executor.execute(new RunnableTask1());
    executor.execute(new RunnableTask2());
    

    因此,如果您想重用线程,请使用ExecutorServiceThreadPoolExecutor 创建一个线程池,这样池中的一个线程将执行可运行的任务。

    如果所有线程都忙,任务将排队到一定的限制,之后将通过RejectedExecutionException 被拒绝。

    示例

    public class NewMain { 
    
        private static final ExecutorService ex = Executors.newFixedThreadPool(3);
    
        public static void main(String[] args) {
            Runnable r = () -> System.out.println(Thread.currentThread().getName());
            ex.execute(r);
    
            CompletableFuture<Void> c = CompletableFuture.runAsync(r, ex);
        }
    }
    

    Jdk-8使用CompletableFuture.runAsync并传递runnable,Executor

    public static CompletableFuture runAsync(Supplier 供应商, 执行者执行者)

    返回一个新的 CompletableFuture,它在运行给定操作后由给定执行器中运行的任务异步完成。

    【讨论】:

    • 嗯,但这如何与 CompletableFuture 集成? TMK,CompletableFuture 使用自己的线程,有时是多个线程。我的目标是告诉 CompletableFuture 使用来自特定池的线程,所以我不确定这是否能回答我的问题。
    • 我更新了 OP 以使问题更清晰一些,让我知道是否是
    猜你喜欢
    • 2018-12-11
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    相关资源
    最近更新 更多