Khushi
Khushi

Reputation: 333

ExecutorService should be alive for whole life of bean or should have narrow(method) scope

I have a method, which has to process thousand of documents.

It takes time in normal processing so I use ExecutorService to reduce processing time by having multiple threads working in parallel.

I have to use this method for processing of two long lists.

  1. Approach 1 of handling ExecutorService:

Right now , I have initialized ExecutorService within method and shutting down it in same method. (which is called twice)

So it leads to creation and shutting down of ExecutorService twice.

  private List<DocDTO> convertData(args) {
    ExecutorService service = Executors.newFixedThreadPool(threads);

    List<Future<Set<DocDTO>>> futures = new ArrayList<Future<Set<DocDTO>>>();

    for (Pro pro : pros.getPros()) {
        Callable<Set<DocDTO>> callable = new Callable<Set<DocDTO>>() {
            public Set<DocDTO> call() throws Exception {        
                for loop code
            }
        };
        futures.add(service.submit(callable));
    }

    service.shutdown();
    for (Future<Set<DocDTO>> future : futures) {
        if (future.get() != null) {
            list.addAll(future.get());
        }
    }   
}   
  1. Approach 2 of handling ExecutorService:

I was looking at below link:

http://programtalk.com/java/executorservice-not-shutting-down/

Author has created ExecutorService at Class level.

Could you please tell me if it is good idea to have ExecutorService created at method level or class level?

FYI , method in above code gets executed twice in a day

Upvotes: 1

Views: 4357

Answers (3)

Khushi
Khushi

Reputation: 333

Thanks Maleen and GhostCat for your valuable comments, i dropped plan of using multiple threads because of two reasons:

  • I was getting different results from the same method while running from single thread and multiple thread

  • ExecutorService does not work with Lazy relationship. So changing Entities' loading from Lazy to Eager might affect other functionality performance

Instead I optimized the way how I was loading entities rather than using multi threading. Previously, I was loading all static data from database one by one in for loop and saving it in EhCache .

After change I loaded all static data in one go using findall methods and saved in map and accessed same data from map in for loop . It increased performance of method a lot. Thank you again to both of you.

Upvotes: 0

Maleen Abewardana
Maleen Abewardana

Reputation: 14552

First I would recommend you to read this doc where you can understand how to use spring to enable a task executor service. As correctly suggested by GhostCat it should be in class level. Further I would suggest is creating a seperate bean for it.

Ex:

@Bean
public TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(10);
    executor.setQueueCapacity(25);
    return executor;
}

I got it from this answer, but there are plenty of different configuration you can find on internet.

Upvotes: 1

GhostCat
GhostCat

Reputation: 140427

The natural choice is to make such a service a class field.

Establishing such a service doesn't come for free. You spent that overhead for "building" that thread pool; and the time to properly shut it down - each time that method is called.

Most of the time, that is not what you want. You want to spend that time once (like: when the object holding the service gets created).

The one downside: now the "life time" of the class holding the service matters. As you now might have to worry about explicit calls to shutdown() the service owned by that holder class.

In other words: when you have to worry about performance, then you would probably change the service to be a field of a class.

But: you explicitly state that this method is called two times per day. Then you absolutely do not need to worry about the overhead generated by creating/closing down that service. Even when the overhead would result in 1 second of computing time - 2 seconds per day do simply not matter at all.

So, given that requirement - my (personal) advise: keep your code as is. Don't touch a running system until there is a real problem to fix.

Upvotes: 2

Related Questions