Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring equivalent of CompletionService?

In my app I have to process multiple jobs asynchronously from the main application thread and collect the result of each job. I have a plain Java solution that does this using a ExecutorService and a ExecutorCompletionService that collects the job results.

Now I would like to convert my code to a Spring solution. The docs show me how the use the ExecutorService and the @Async annotation, but I am not sure how and if I can collect the results of multiple jobs.

In other words: I am looking for the Spring equivalent of the CompletionService. Is there such a thing?

My current code:

class MyService {

private static ExecutorService executorService;
private static CompletionService<String> taskCompletionService;

// static init block
static {
    executorService = Executors.newFixedThreadPool(4);
    taskCompletionService = new ExecutorCompletionService<String>(executorService);

    // Create thread that keeps looking for results
    new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                try {
                    Future<String> future = taskCompletionService.take();
                    String s = future.get();
                    LOG.debug(s);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }

    }).start();
}

// This method can and will be called multiple times, 
// so multiple jobs are submitted to the completion service
public void solve(List<Long> ids) throws IOException, SolverException {
    String data = createSolverData(ids);
    taskCompletionService.submit(new SolverRunner(data, properties));
}
}
like image 472
Julius Avatar asked Nov 12 '22 02:11

Julius


1 Answers

You need to consider what's your main goal, because your current code will work fine alongside other Spring-associated classes. Spring provides support for native Java ExecutorService as well as other popular 3rd party library such as Quartz

Probably what you're after is setting up the executor service on the spring container (eg: using following config on your spring beans xml)

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <property name="corePoolSize" value="5" />
  <property name="maxPoolSize" value="10" />
  <property name="queueCapacity" value="25" />
</bean>

And decorate your MyService class with @Service annotation and inject the reference to the executor service

like image 92
gerrytan Avatar answered Nov 15 '22 07:11

gerrytan