Весенний эквивалент CompletionService?

В моем приложении я должен асинхронно обрабатывать несколько заданий из основного потока приложения и собирать результат каждого задания. У меня есть простое Java-решение, которое делает это с помощью ExecutorService и ExecutorCompletionService, которые собирают результаты задания.

Теперь я хотел бы преобразовать свой код в решение Spring. В документах показано, как использовать ExecutorService и @Async, но я не уверен, как и смогу ли я собирать результаты нескольких заданий.

Другими словами: я ищу Spring-эквивалент CompletionService. Что-то подобное существует?

Мой текущий код:

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));
}
}

person Julius    schedule 24.06.2013    source источник


Ответы (2)


Вам нужно подумать, какова ваша основная цель, потому что ваш текущий код будет нормально работать вместе с другими классами, связанными со Spring. Spring обеспечивает поддержку собственного Java ExecutorService, а также других популярных сторонних библиотек, таких как Quartz.

Вероятно, вам нужна настройка службы исполнителя в контейнере Spring (например: использование следующей конфигурации в вашем 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>

И украсьте свой класс MyService аннотацией @Service и добавьте ссылку на службу-исполнитель.

person gerrytan    schedule 24.06.2013

В итоге я определил свои bean-компоненты в контексте приложения Spring и внедрил службу завершения в MyService. Работает как оберег.

<task:executor id="solverExecutorService" pool-size="5" queue-capacity="100" />
<spring:bean id="solverCompletionService" class="nl.marktmonitor.solver.service.SolverCompletionService" scope="singleton">
    <constructor-arg name="executor" ref="solverExecutorService"/>
</spring:bean>
person Julius    schedule 28.06.2013