Quelle est la différence entre ExecutorService.soumettre et ExecutorService.exécuter dans le présent code en Java?
Je suis en train d'apprendre à utiliser ExectorService
à la piscine threads
et d'envoyer des tâches. J'ai un simple programme ci-dessous
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
class Processor implements Runnable {
private int id;
public Processor(int id) {
this.id = id;
}
public void run() {
System.out.println("Starting: " + id);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("sorry, being interupted, good bye!");
System.out.println("Interrupted "+Thread.currentThread().getName());
e.printStackTrace();
}
System.out.println("Completed: " + id);
}
}
public class ExecutorExample {
public static void main(String[] args) {
Boolean isCompleted=false;
ExecutorService executor = Executors.newFixedThreadPool(2);
for(int i=0; i<5; i++) {
executor.execute(new Processor(i));
}
//executor does not accept any more tasks but the submitted tasks continue
executor.shutdown();
System.out.println("All tasks submitted.");
try {
//wait for the exectutor to terminate normally, which will return true
//if timeout happens, returns false, but this does NOT interrupt the threads
isCompleted=executor.awaitTermination(100, TimeUnit.SECONDS);
//this will interrupt thread it manages. catch the interrupted exception in the threads
//If not, threads will run forever and executor will never be able to shutdown.
executor.shutdownNow();
} catch (InterruptedException e) {
}
if (isCompleted){
System.out.println("All tasks completed.");
}
else {
System.out.println("Timeout "+Thread.currentThread().getName());
}
}
}
Il ne fait rien de fantaisie, mais crée deux threads
et présente 5 tâches au total. Après chaque thread
termine sa tâche, il prend le prochain,
Dans le code ci-dessus, j'utilise executor.submit
. J'ai aussi changé de executor.execute
. Mais je ne vois pas la différence dans la sortie. En quoi les submit and execute
méthodes différentes?
Ce que la API
dit
Méthode soumettre s'étend de la base de la méthode de l'Exécuteur testamentaire.execute(java.lang.Runnable) par la création et le retour d'un Avenir qui peut être utilisé pour annuler l'exécution et/ou de patienter. Méthodes invokeAny et invokeAll effectuer le plus couramment formes utiles de la masse de l'exécution, l'exécution d'une collection de tâches, puis attendre au moins un, ou tous, pour compléter. (Classe ExecutorCompletionService peut être utilisé pour écrire personnalisé variantes de ces méthodes.)
Mais ce n'est pas clair pour moi que ce que cela signifie exactement?
Vous devez vous connecter pour publier un commentaire.
Comme vous le voyez sur la JavaDoc
execute(Runnable)
ne retourne rien.Cependant,
submit(Callable<T>)
renvoie uneFuture
objet qui permet à un moyen pour vous de par programmation d'annuler le thread en cours d'exécution plus tard, ainsi que d'obtenir laT
retourné lorsque laCallable
complète. Voir JavaDoc de l'Avenir pour plus de détailsEn outre,
si
future.get() == null
et de ne pas jeter d'exception alors Praticable exécutée avec succèsLa différence est que
execute
commence simplement à la tâche sans plus tarder, tandis quesubmit
renvoie uneFuture
objet pour gérer la tâche. Vous pouvez faire les choses suivantes avec leFuture
objet:cancel
méthode.get
.La
Future
interface est plus utile si vous soumettez uneCallable
à la piscine. La valeur de retour de lacall
méthode sera retourné lorsque vous appelezFuture.get
. Si vous n'avez pas maintenir une référence à laFuture
, il n'y a pas de différence.execute:
L'utiliser pour le feu et oublier les appelssubmit:
L'utiliser pour inspecter le résultat de l'appel de méthode et de prendre les mesures appropriées surFuture
opposé retourné par l'appelDifférence majeure:
Exception
manipulationsubmit()
masque non-traitéeException
dans le cadre lui-même.execute()
jette non-traitéeException
.Solution pour la gestion des Exceptions avec
submit()
Envelopper votre
Callable or Runnable code in try{} catch{} block
OU
Garder
future.get() call in try{} catch{} block
OU
mettre en place votre propre
ThreadPoolExecutor
et remplacerafterExecute
méthodeConcernant le tour d'autres questions sur la
invokeAll:
invokeAny:
Utilisation
invokeAll
si vous voulez attendre pour toutes les tâches à effectuer.Utilisation
invokeAny
si vous êtes à la recherche pour la réalisation d'une tâche de N soumis tâches. Dans ce cas, les tâches en cours sera annulée si l'une des tâches se termine avec succès.Related post avec le code exemple:
Choisissez entre ExecutorService de soumettre et ExecutorService execute
submit
ne pas "cacher" une exception, il le jette enveloppé dansExecutionException
quandget
est appelé. L'exception d'origine peuvent ensuite être récupérés parExecutionException.getCause()
De soumettre les Rendements Futurs de l'objet, qui peut être utilisé pour vérifier le résultat de la tâche. Peut être utilisé pour annuler ou pour vérifier isDone etc.
Exécution - ne retourne rien.
Un principale différence entre les soumettre() et execute() la méthode est que ExecuterService.submit()peut retourner le résultat de calcul car il a un type de retour de l'Avenir, mais la méthode execute() ne retourne rien, parce que c'est le type de retour est void. Le cœur de l'interface en Java 1.5 l'Exécuteur de cadre est l'Exécuteur testamentaire de l'interface qui définit les exécuter(Runnable tâche) de la méthode, dont le principal but est de séparer la tâche de son exécution.
Toutes les tâches soumises à l'Exécuteur testamentaire peut être exécutée par le même thread, un thread de travail à partir d'un pool de threads ou de toute autre thread.
D'autre part, la méthode submit() est définie dans le ExecutorService interface qui est une sous-interface de l'Exécuteur testamentaire et ajoute les fonctionnalités de la résiliation du pool de threads, avec l'ajout de méthode submit() qui peut accepter un Callable tâche et retourne un résultat de calcul.
Similitudes entre le execute() et de le soumettre() ainsi:
Hormis le fait que la méthode submit() peut renvoyer des résultats et execute() ne peut pas, en voici d'autres différences notables entre ces deux principales méthodes de l'Exécuteur testamentaire cadre de Java 5.
Si vous consultez le code source, vous verrez que
submit
est une sorte de wrapper surexecute
essentiellement deux appels d'exécuter,si tu veux avenir de l'objet que vous appellerons méthode submit()
voici de la doc
comme vous pouvez le voir java a vraiment aucun moyen de démarrer un thread autre que l'appel de méthode run() de l'OMI. depuis j'ai aussi trouvé que
Callable.call()
méthode est appelée à l'intérieur d'run()
méthode. ainsi, si l'objet est remboursable, il serait toujours appelerrun()
méthode, qui inturn appelleraiscall()
méthodede doc.