2013-06-22 13 views
16

Sto tentando di implementare un task spring @Async che ha un tipo di ritorno di Future, ma non riesco a capire come farlo correttamente.Spring 3.2 @Async task con tipo di ritorno del futuro

  1. Che cosa otterrò facendo così? ora avrò un controllo sul mio compito in modo che possa fermarlo ed eseguirlo?
  2. Esiste un'implementazione di riferimento su come posso farlo? SpringSource non ne fornisce.

EDIT

Da sorgenti molla e manuale molla refrence:

Anche metodi che restituiscono un valore può essere richiamato in modo asincrono. Tuttavia, tali metodi sono richiesti per avere un valore di ritorno digitato per futuro. Ciò offre ancora il vantaggio dell'esecuzione asincrona in modo che il chiamante possa eseguire altre attività prima di chiamare get() su quel futuro.

e dà un esempio in questo modo:

@Async 
Future<String> returnSomething(int i) { 
// this will be executed asynchronously 
} 

Come implementare correttamente questo?

risposta

21

Partenza this blog post.

Utilizzando @Async consente di eseguire un calcolo in un metodo in modo asincrono. Ciò significa che se viene chiamato (su un bean gestito Spring), il controllo viene immediatamente restituito al chiamante e il codice nel metodo viene eseguito in un altro thread. Il chiamante riceve un oggetto Future associato al calcolo in esecuzione e può utilizzarlo per verificare se il calcolo è in esecuzione e/o attendere il risultato.

Creazione di un tale metodo è semplice. Annotalo con @Async e avvolgi il risultato in AsyncResult, come mostrato nel post del blog.

+1

questo è quello che stavo cercando – engma

+0

quindi questo significa che io può interrompere il mio compito in qualsiasi momento se non è già stato cancellato? – engma

+3

@ Developer106 Sì, è possibile _interrupt_ il metodo asincrono chiamando [cancel (true)] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html#cancel (booleano)) sul 'futuro' restituito. Ma l'interruzione non funziona automaticamente. O il metodo dovrebbe controllare l'interruzione chiamando 'Thread.isInterrupted()' o utilizzare metodi che generano 'InterruptedException'. Vedi [Interrupts] (http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html) in The Java Tutorial. –

2

ExecutorService può pianificare Callable e restituire un oggetto Future. The Future è un segnaposto che contiene i risultati una volta disponibile. Ti consente di controllare se il risultato è presente, annullare l'attività o bloccare e attendere i risultati. The Future è utile solo quando ti aspetti qualche oggetto/valore dall'attività.

modo corretto di fare la chiamata futuro è:

Future<Integer> futureEvenNumber = executorService.submit(new NextEvenNumberFinder(10000)); 

// Do something. 

try { 
    Integer nextEvenNumber = futureEvenNumber.get(); 
} catch (ExecutionException e) { 
    System.err.println("NextEvenNumberFinder threw exception: " + e.getCause()); 
} 

La classe NextEvenNumberFinder:

public class NextEvenNumberFinder implements Callable<Integer> { 
private int number; 

public NextEvenNumberFinder(int number) { this.number = number; } 

@Override 
public Integer call() throws Exception { 
    for (;;) 
     if (isEvenNumber(++number)) return number; 
} 

}

Manuale di Primavera Integrazione Riferimento: http://static.springsource.org/spring-integration/reference/htmlsingle/

+0

aggiornerò la mia risposta in modo da poter ottenere ciò che intendo – engma

2

Dai un'occhiata a questo blog post

configurazione Importante è:

  1. @Async sulla primavera gestito metodo di fagioli
  2. Abilita asincrono in primavera config xml definendo:

    <!-- Enables the detection of @Async and @Scheduled annotations on any Spring-managed object. --> 
         <task:annotation-driven/> 
    

    SimpleAsyncTaskExecutor verrà utilizzato per impostazione predefinita.

Avvolgere la risposta in una delle prossime <> oggetto

Esempio:

@Async 
    public Future<PublishAndReturnDocumentResult> generateDocument(FooBarBean bean) { 
//do some logic 
return new AsyncResult<PublishAndReturnDocumentResult>(result); 


} 

si può quindi controllare se il risultato è fatto (result.isDone()) o attendere per ottenere la risposta result.get()

Problemi correlati