我有一个处理主实体的服务,检索与主实体关联的第一个子实体,然后返回两者。它还引发了一系列可完成的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多名用户进行此项运行的最快速度,但它仍然会大幅降低我添加的用户数量。
答案 0 :(得分:3)
正如您最有可能知道的那样,有一种方法Thread::setPriority
。但至于JavaDoc
每个帖子都有优先权。执行具有更高优先级的线程 优先于优先级较低的线程。
因此,您可以在创建缓存ThreadFactory
时提供ExecutorService
。
实际的线程调度详细信息是特定于VM的实现,因此您无法真正依赖于此。我会考虑使用fixedThreadPool
但我不确定实际问题是关于线程调度和优先级。首先,缓存的线程池可以(至于文档)
创建一个线程池,根据需要创建 新线程 ,但是 在先前构造的线程可用时重用它们。
如果有50个以上的用户可以调用buildFutureTasks
,则无法真正控制创建的线程数。
我会考虑使用fixedThreadPool
,以便您可以控制是否真的需要SynchronousQueue
这是缓存线程池的基础。
考虑对所有任务使用相同的ThreadPool
,而不是每次调用时都在方法buildFutureTasks
内创建它。