简体   繁体   中英

Working with ExecutorService with smaller thread pool than tasks

I have question about ExecutorService. I have list of Status , each of this status contains list of person that have this status. What i want to do is

  1. retrieve list of statuses
  2. i want to process every person in status S, concurently.
  3. when processing of status S is done, i want to process status S1 the same way, until every status was processed
  4. return all processed persons

I have this code

ExecutorService threadExecutor = Executors.newFixedThreadPool(10);
List<Status> statusList = getStatusList();
List<PersonInfoWrapper> personInfoWrapperList = new ArrayList<>();

for(Status status: statusList ){
    List<PersonInfo> personInfo = status.getPersonList();
    List<Future<PersonInfoWrapper> futures = new ArrayList<>();

    for(PersonInfo info : personInfo){
         Future<PersonInfoWrapper> future = threadExecutor.submit(() -> processInfo(info));
         futures.add(future);
    }

    for(Future<PersonInfoWrapper> future : futures ){
         personInfoWrapperList .add(future.get());
    }
}
threadExecutor.shutdown();

My questions are:

  1. The ExecutorService has threadpool of 10. However there are more persons than 10 for each status. When i process it concurrently ( as indicated in second for loop ), and then call future.get() in the third for loop, doesnt it block the execution of the other tasks in ExecutorService?

  2. Is it okay to reuse ExecutorService like this? Shouldnt i use new executor service for every status i am about to process?

  1. I would suggest you to use Executors.newCachedThreadPool(), so if you have more persons then threads this poll will create new threads automatically as needed and will reuse previously constructed threads when they are available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources.

Future offers you method isDone() which is not blocking and returns true if computation has completed, false otherwise.

Future.get() is used to retrieve the result of computation.

You have a couple of options:

  • call isDone() and if the result is ready ask for it by invoking get(), notice how there is no blocking
  • block indefinitely with get()
  • block for specified timeout with get(long timeout, TimeUnit unit)
  1. It's a bad idea to create multiple executorService instances. Therefore, yes, you should reuse an existing one.

Hope, that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM