通过CompletableFuture强制重用线程

时间:2019-02-07 00:50:58

标签: java multithreading executorservice threadpoolexecutor completable-future

我正在严格使用:

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

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

更新

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

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

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

2 个答案:

答案 0 :(得分:1)

为每组任务创建

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并传递可运行的执行器

公共静态CompletableFuture runAsync(供应商,                                                    执行者执行者)

  

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

答案 1 :(得分:1)

  

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

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

  

8个处理器

(2)如果机器确实支持并行性,那么我猜想使用ForkJoinPool.commonPool()并将并行度级别设置为可用处理器的数量(可以由Runtime#availableProcessors确定)。

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

  

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

DelayedExecutor只是将任务提交给基础Executor,该基础可以是ThreadPerTaskExecutor(1)或ForkJoinPool(2)。

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

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

这使我们回到your previous question,在这里我pointed out可以用Executor来定义ThreadFactory

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