différence entre exécuteur testamentaire.soumettre et exécuteur testamentaire.exécuter dans ce code en Java?
j'apprends à utiliser exectorServices
pour regrouper threads
et envoyer des tâches. J'ai un programme simple en dessous de
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 fantaisiste, mais crée deux threads
et soumet 5 tâches au total. Après chaque thread
complète sa tâche, il prend le suivant,
Dans le code ci-dessus, j'utilise executor.submit
. J'ai aussi changé en executor.execute
. Mais je ne vois aucune différence dans la sortie. En quoi les submit and execute
méthodes différentes?
Ce qu' le API
dit
Méthode de soumettre s'étend de la base de la méthode de l'Exécuteur testamentaire.execute (java.lang.Runnable) en créant et retournant un futur qui peut être utilisé pour annuler l'exécution et/ou attendre l'achèvement. Méthodes invokeAny et invokeAll exécutent les formes les plus couramment utiles d'exécution en vrac, en exécutant un ensemble de tâches et en attendant au moins un, ou tous, à compléter. (Class Executorcompleletionservice peut être utilisé pour écrire des variantes personnalisées de ces méthodes.)
mais ce n'est pas clair pour moi ce que cela signifie exactement? Merci
5 réponses
comme vous le voyez de la JavaDoc execute(Runnable)
ne renvoie rien.
cependant, submit(Callable<T>)
renvoie un objet Future
qui vous permet d'annuler programmatiquement le thread plus tard ainsi que d'obtenir le T
qui est retourné lorsque le Callable
est terminé. Voir JavaDoc du futur pour plus de détails
Future<?> future = executor.submit(longRunningJob);
...
//long running job is taking too long
future.cancel(true);
de plus,
si future.get() == null
et ne jette aucune exception alors Exécutable exécuté avec succès
la différence est que execute
commence simplement la tâche sans plus attendre, alors que submit
renvoie un objet Future
pour gérer la tâche. Vous pouvez faire les choses suivantes avec l'objet Future
:"
- annuler la tâche prématurément, avec la méthode
cancel
. - attendre la fin de la tâche d'exécution, avec
get
.
l'interface Future
est plus utile si vous soumettez une Callable
à la piscine. La valeur de retour de la méthode call
sera retournée lorsque vous appellerez Future.get
. Si vous ne maintenez pas une référence au Future
, il n'y a pas de différence.
execute:
l'Utiliser pour le feu et oublier appelle
submit:
l'Utiliser pour inspecter le résultat de l'appel de méthode et de prendre des mesures appropriées Future
opposé retourné par l'appel
différence majeure: Exception
manipulation
submit()
se cache Non manipulé Exception
dans le cadre lui-même.
execute()
lancers un-handled Exception
.
Solution pour le traitement des Exceptions avec submit()
-
enveloppez 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éthode
concernant la visite d'autres questions sur
exécute les tâches données, en retournant une liste de Futures détenant leur statut et les résultats lorsque tout terminé ou le délai expire, selon ce qui se produit en premier.
exécute les tâches données, en retournant le résultat d'un qui a complété avec succès (c. - à-d., sans lancer une exception), s'il y a faire avant l'expiration du délai donné.
utilisez invokeAll
si vous voulez attendre que toutes les tâches soumises à compléter.
utilisez invokeAny
si vous recherchez l'exécution réussie d'une tâche sur N tâches soumises. Dans ce cas, les tâches en cours seront annulées si l'une d'entre elles est accomplie avec succès.
POSTE Associé Avec exemple de code:
Choisir entre ExecutorService de soumettre et ExecutorService execute
soumettre-renvoie L'objet futur, qui peut être utilisé pour vérifier le résultat de la tâche soumise. Peut être utilisé pour annuler ou pour vérifier isDone etc.
Exécuter - ne retourne rien.
essentiellement les deux appels exécutent,si vous voulez un objet futur vous devez appeler la méthode submit() ici du doc
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
comme vous pouvez le voir java n'a vraiment aucun moyen de démarrer un thread autre que d'appeler la méthode run (), IMO. puisque j'ai également trouvé que Callable.call()
méthode est appelé à l'intérieur run()
méthode. par conséquent, si l'objet est appelable, il appellerait encore la méthode run()
, qui appellerait la méthode call()
.
de doc.
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}