ExecutorService vs Casual Fil des Reproducteurs

J'ai une question de base sur la façon ExecutorService fonctionne en Java.

Il est assez difficile de voir la différence entre la création d' Threads pour effectuer certaines tâches en parallèle et en attribuant à chacun des tâches à l' ThreadPool.

La ExecutorService l'air également très simple à utiliser et efficace, alors je me demandais pourquoi nous n'utilisons pas tout le temps.

Est-ce juste une question de façon de l'exécution de son travail plus vite que les autres ?

Voici deux exemples très simples pour montrer la différence entre les deux façons :

À l'aide de l'exécuteur de service: Bonjour tout le Monde (tâche)

static class HelloTask implements Runnable {
    String msg;

    public HelloTask(String msg) {
        this.msg = msg; 
    }
    public void run() {
        long id = Thread.currentThread().getId();
        System.out.println(msg + " from thread:" + id);
    }
}

À l'aide de l'exécuteur de service: Bonjour tout le Monde (la création d'exécuteur testamentaire, l'envoi)

static class HelloTask {
    public static void main(String[] args) {
        int ntasks = 1000;
        ExecutorService exs = Executors.newFixedThreadPool(4);

        for (int i=0; i<ntasks; i++) { 
            HelloTask t = new HelloTask("Hello from task " + i);    
            exs.submit(t);
        }
        exs.shutdown();
    }
}

la figure suivante montre un exemple similaire, mais qui s'étend le Callable interface, pourriez-vous me dire la différence entre les deux et dans quels cas on doit utiliser un spécifique à la place de l'autre ?

À l'aide de l'exécuteur de service: Comptoir (tâche)

static class HelloTaskRet implements Callable<Long> {
    String msg;

    public HelloTaskRet(String msg) {
        this.msg = msg; }

        public Long call() {
        long tid = Thread.currentThread().getId(); 
        System.out.println(msg + " from thread:" + tid); 
        return tid;
    } 
}

À l'aide de l'exécuteur de service: (la création, la soumission)

static class HelloTaskRet {
    public static void main(String[] args) {
        int ntasks = 1000;
        ExecutorService exs = Executors.newFixedThreadPool(4);

        Future<Long>[] futures = (Future<Long>[]) new Future[ntasks];

        for (int i=0; i<ntasks; i++) { 
            HelloTaskRet t = new HelloTaskRet("Hello from task " + i);
            futures[i] = exs.submit(t);
        }
        exs.shutdown();
    }
}
Les deux exemples d'utilisation ExecutorService au lieu de créer de nouveaux Threads, donc je ne suis pas sûr de ce que vous êtes de la comparaison entre les 2 exemples dans ce cas. Est votre confusion sur l'utilisation de Runnable et quand utiliser Callable?

OriginalL'auteur Phil Moesch | 2014-11-14