J'apprends à utiliser ExectorService
à la piscine threads
et envoyer des tâches. J'ai un programme simple 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 d'extraordinaire, mais crée deux threads
et soumet 5 tâches au total. Après chaque thread
termine sa tâche, il prend la suivante, Dans le code ci-dessus, j'utilise executor.submit
. J'ai également changé pour executor.execute
. Mais je ne vois aucune différence dans la sortie. De quelle manière les submit
y execute
méthodes différentes ? Voici ce que le API
dit
La méthode submit étend la méthode de base Executor.execute(java.lang.Runnable) en créant et en renvoyant un Future qui peut être utilisé pour annuler l'exécution et/ou attendre l'achèvement. Les méthodes invokeAny et invokeAll exécutent les formes les plus courantes d'exécution en masse, en exécutant un ensemble de tâches et en attendant qu'au moins l'une d'entre elles, voire toutes, se termine. (La classe ExecutorCompletionService peut être utilisée pour écrire des variantes personnalisées de ces méthodes).
Mais je ne comprends pas bien ce que cela signifie exactement ?