代码之家  ›  专栏  ›  技术社区  ›  Alexander Mills

通过CompletableFuture强制重新使用线程

  •  2
  • Alexander Mills  · 技术社区  · 7 年前

    我正在关键地利用:

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

    从我在网上读到的内容来看,每次通话都使用一个新线程是很常见的。我想知道是否有一种方法可以重复使用一个线程,而不是创建新的线程?

    使现代化 :

    我不清楚-我想用 CompletableFuture 但是我想要 完全的未来 重用某个线程,而不是管理它自己的线程。

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

    但它建议使用环境变量——我想知道是否有一种方法可以通过编程实现这一点。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Andrew    7 年前

    从我在网上读到的内容来看,每次通话都使用一个新线程是很常见的。

    (1) 只有当机器不支持并行性,或者通过设置系统属性使其不支持并行性时,才会出现这种情况 java.util.concurrent.ForkJoinPool.common.parallelism 到 0 或 1 .

    8处理器

    (2) 如果机器支持并行, ForkJoinPool.commonPool() 我猜,并行级别设置为可用处理器的数量(可由 Runtime#availableProcessors ).

    在一个有8个处理器的场景中,可能会创建7-8个线程来服务公共应用程序 ForkJoinPool .

    我想用 CompletableFuture 但是我想要 完全的未来 重用某个线程,而不是管理它自己的线程。

    A. DelayedExecutor 只需将任务提交给底层 Executor ,即 ThreadPerTaskExecutor (1) 或者 叉子池 (2).

    幸运的是,您可以手动指定 遗嘱执行人 将由 延迟执行器 把任务委派给。

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

    它让我们回到 your previous question ,我在那里 pointed out 那是 遗嘱执行人 可以用 ThreadFactory .

    Executor executor = Executors.newCachedThreadPool(YourThreadClass::new);
    
        2
  •  1
  •   Ryuzaki L    7 年前

    遗嘱执行人 为每一组任务创建新线程

    通常使用执行器,而不是显式地创建线程。例如,不调用新线程(new(RunnableTask()))。start()对于一组任务中的每一项,可以使用:for a set task

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

    因此,如果您想重用线程,可以使用 ExecutorService 或 ThreadPoolExecutor ,因此池中的一个线程将执行可运行任务。

    如果所有线程都很忙,任务将排队到一定的限制,之后将通过 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,遗嘱执行人

    公共静态CompletableFuture runAsync(供应商, 遗嘱执行人(遗嘱执行人)

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