Reputation: 137
I have a service that handles the main entity, retrieves the first sub-entity associated with the main entity, then returns both. It also sets off a set of completable Future
chains to go out & retrieve any additional entities. Currently, I just take a prebuilt set of retrieval tasks, wrap a Future
async around them, then set it off with a CachedThreadPool
. This is fine, but when 50+ users hit the server the primary task (of retrieving the main entity & the first sub-entity) is dramatically slowed by all of the async threads running.
I want to know if there is a way to make the asynchronous calls to run on a lower priority in order to make sure the primary call is handled quickly.
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;
}
This is the fastest I've been able to make this run with 50+ users but it still dramatically slows down the more users I add.
Upvotes: 5
Views: 1345
Reputation: 27435
As you are most likely to know already, there is a method Thread::setPriority
. But as to the JavaDoc
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.
So you can just provide a ThreadFactory
when creating your cached ExecutorService
.
The actual thread scheduling details is VM-implementation specific so you cannot really rely on this. I would consider using fixedThreadPool instead
But I'm not sure that the actual problem is about thread scheduling and priority. First of all, cached thread pool can (as to the documentation)
Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.
In case of 50+ users which can call buildFutureTasks
you cannot really control the number of threads created.
I would consider using fixedThreadPool
so you can control if don't really need SynchronousQueue
which is the underlying of cached thread pools.
Consider using the same ThreadPool
for all the task and not create it inside the method buildFutureTasks
every time it is called.
Upvotes: 3