user1760412
user1760412

Reputation: 137

How to make asynchronous tasks have lower priority in Java 8?

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

Answers (1)

St.Antario
St.Antario

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.

  1. I would consider using fixedThreadPool so you can control if don't really need SynchronousQueue which is the underlying of cached thread pools.

  2. Consider using the same ThreadPool for all the task and not create it inside the method buildFutureTasks every time it is called.

Upvotes: 3

Related Questions