如何使异步任务在Java 8中具有较低的优先级?

时间:2018-01-24 04:28:51

标签: java multithreading asynchronous java-8

我有一个处理主实体的服务,检索与主实体关联的第一个子实体,然后返回两者。它还引发了一系列可完成的Future链出去&检索任何其他实体。目前,我只是采取一组预先构建的检索任务,围绕它们包裹Future异步,然后使用CachedThreadPool将其设置为关闭。这很好,但当50多个用户点击服务器时,所有异步线程运行的主要任务(检索主实体和第一个子实体)都会大大减慢。

我想知道是否有办法让异步调用以较低的优先级运行,以确保快速处理主要调用。

  public CompletableFuture buildFutureTasks(P primaryEntity, List<List<S>> entityGroups)
  {
    ExecutorService pool = Executors.newCachedThreadPool();
    CompletableFuture<Void> future = null;
    for (List<S> entityGroup : entityGroups)
    {
      if (future == null || future.isDone())
      {
        future = CompletableFuture.runAsync(() ->
            retrieveSubEntitiesForEntity(primaryEntity, entityGroup), pool);
      }
      else
      {
        future.thenRunAsync(() ->
            retrieveSubEntitiesForEntities(primaryEntity, entityGroup), pool);
      }
    }
    return future;
  }

这是我能用50多名用户进行此项运行的最快速度,但它仍然会大幅降低我添加的用户数量。

1 个答案:

答案 0 :(得分:3)

正如您最有可能知道的那样,有一种方法Thread::setPriority。但至于JavaDoc

  

每个帖子都有优先权。执行具有更高优先级的线程   优先于优先级较低的线程。

因此,您可以在创建缓存ThreadFactory时提供ExecutorService。 实际的线程调度详细信息是特定于VM的实现,因此您无法真正依赖于此。我会考虑使用fixedThreadPool

但我不确定实际问题是关于线程调度和优先级。首先,缓存的线程池可以(至于文档)

  

创建一个线程池,根据需要创建 新线程 ,但是   在先前构造的线程可用时重用它们。

如果有50个以上的用户可以调用buildFutureTasks,则无法真正控制创建的线程数。

  1. 我会考虑使用fixedThreadPool,以便您可以控制是否真的需要SynchronousQueue这是缓存线程池的基础。

  2. 考虑对所有任务使用相同的ThreadPool,而不是每次调用时都在方法buildFutureTasks内创建它。