use*_*412 5 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;
}
Run Code Online (Sandbox Code Playgroud)
这是我在 50 多个用户的情况下运行的最快速度,但它仍然大大减慢了我添加的更多用户的速度。
正如您很可能已经知道的那样,有一种方法Thread::setPriority。但至于JavaDoc
每个线程都有一个优先级。具有较高优先级的线程优先于具有较低优先级的线程执行。
因此,您只需ThreadFactory在创建缓存时 提供一个ExecutorService. 实际的线程调度细节是特定于虚拟机实现的,所以你不能真正依赖它。我会考虑使用fixedThreadPool代替
但我不确定实际的问题是关于线程调度和优先级。首先,缓存线程池可以(至文档)
创建一个线程池,该线程池根据需要创建新线程,但会重用以前构造的线程(当它们可用时)。
如果有 50 多个用户可以调用,buildFutureTasks您无法真正控制创建的线程数量。
我会考虑使用fixedThreadPool,这样您就可以控制是否真的需要SynchronousQueue哪个是缓存线程池的底层。
ThreadPool考虑对所有任务使用相同的方法,而不是buildFutureTasks每次调用方法时都在方法内创建它。
| 归档时间: |
|
| 查看次数: |
1173 次 |
| 最近记录: |