5

Nella mia app devo elaborare più processi in modo asincrono dal thread dell'applicazione principale e raccogliere il risultato di ogni lavoro. Ho una semplice soluzione Java che fa questo utilizzando un ExecutorService e un ExecutorCompletionService che raccoglie i risultati del lavoro.Equivalente di primavera di CompletionService?

Ora vorrei convertire il mio codice in una soluzione Spring. Lo docs mi mostra come utilizzare l'ExecutorService e l'annotazione @Async, ma non sono sicuro di come e se posso raccogliere i risultati di più lavori.

In altre parole: Sto cercando l'equivalente Spring del servizio di completamento. C'è una cosa del genere?

mio codice corrente:

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

risposta

1

È necessario considerare che cosa è il vostro obiettivo principale, perché il codice attuale funziona bene al fianco di altre classi primavera-associata. Spring fornisce supporto per Java ExecutorService nativo e altre popolari librerie di terze parti come Quartz

Probabilmente quello che stai cercando è impostare il servizio executor sul contenitore spring (ad esempio: utilizzando la seguente configurazione sui bean spring 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> 

e decorare la vostra classe MyService con @Service annotazione e iniettare il riferimento al servizio esecutore

0

ho finito per definire i miei fagioli nel contesto dell'applicazione primavera e l'iniezione del completionservice in MyService. Funziona come un fascino.

<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>