Question

Je suis confus sur ce qui suit:
Pour utiliser threads dans un programme Java, la façon la plus simple est d'étendre classe Thread et mettre en œuvre l'interface Runnable (ou tout simplement mettre en œuvre runnable).
Pour commencer l'exécution du thread. nous devons appeler la méthode du fil de départ (), qui appelle à son tour la méthode run () du fil. Et si le fil commence.
Le début de la méthode () (à moins que je me trompe) doit être appelée exactement et une seule fois pour chaque thread. En conséquence, les instances de fil ne peuvent pas être réutilisées à moins d'une certaine manière la méthode d'exécution exécute lui-même dans une courte de boucle infinie qui facilite une implémentation personnalisée de réutilisations du fil.
Maintenant, le javadoc

Était-ce utile?

La solution

Notez qu'il est Executor pas que les appels start() - c'est ExecutorService. Et non, ce n'est pas appeler start() deux fois. Il ne démarre pas la tâche que vous lui donnez directement à l'aide Thread.start() ... à la place, il commence un fil qui sait que la file d'attente de pool de threads de travail. Le fil sera essentiellement attendre qu'il y ait du travail à faire, puis le ramasser et l'exécuter, avant de retourner à l'attente. Ainsi, bien que le thread effectue plusieurs tâches, Thread.start() est appelée une seule fois.

EDIT:. A en juger par les commentaires, vous êtes un peu confus au sujet de la différence entre un Runnable (ce qui est une tâche à exécuter) et un Thread (qui est ce qui exécute des tâches)

Le même thread peut exécuter des tâches multiples. Pour un exemple très simple de ne pas utiliser un pool de threads, considérez ceci:

public class MultiRunnable implements Runnable
{
    private final List<Runnable> runnables;

    public MultiRunnable(List<Runnable> runnables)
    {
        this.runnables = runnables;
    }

    public void run()
    {
        for (Runnable runnable : runnables)
        {
             runnable.run();
        }
    }
}

(ignorer les problèmes potentiels de sécurité du fil d'utiliser un List<T> de plusieurs threads.)

Vous pouvez créer un tas de tâches de Runnable capables de faire des choses différentes, puis créer un seul MultiRunnable pour les exécuter à son tour. Passer cette instance de MultiRunnable dans le constructeur de Thread, puis lorsque vous démarrez le fil, il exécutera chacune des tâches exécutables d'origine. Est-ce que l'aide?

Autres conseils

Il ne demande pas début () plus d'une fois; à la place du fil dans la piscine ne se termine jamais, mais reste juste en vie --- attente. Le code source est disponible en téléchargement si vous voulez regarder.

Chaque thread dans le pool de threads peut simplement wait() pour le Exécuteur à remettre une nouvelle Runnable, mais propre méthode de run() du thread n'a pas terminé. Il attend simplement une nouvelle Runnable à donner à l'Exécuteur.

Pour « démarrer » un fil plus d'une fois, créez un runnable. Par exemple:

//NO
private class T extends Thread { //not necessary to implement runnable
    public void run(){
        //...
    }
}
void someMethod(){
    T a = new T();
    a.start();
    a.start(); //NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO
}

Au lieu,

//Yes
private class T implements Runnable {
    public void run(){
        //...
    }
}
void someMethod(){
    T a = new T();
    new Thread(a).start();
    new Thread(a).start(); //YES YES YES
}

Il est également possible de faire ceci:

void someMethod(){
    final Runnable r = new Runnable(){
        public void run(){
            //...
        }
    };
    new Thread(r).start();
    new Thread(r).start();
}
// r could also be a field of you class. 
scroll top