Java.lang.IllegalThreadStateException

je travaille avec des fils. Cependant, quand j'essaie de lancer un thread, j'obtiens une Exception. Dans le béton java.lang.IllegalThreadStateException. Mon code est:

public void readCommand() {
    readThread = new Thread("Thread for reading") {
        public void run() {
            while (running) {
                readBuffer = usbservice.receiveData();
                put(readBuffer);
            }
        }
    };
    readThread.start();
}

Quel pourrait être le problème?

22
demandé sur bjb568 2011-09-06 10:51:05

5 réponses

Vous stockez le fil dans un champ. Si la méthode est appelée en deux threads, le readThread.start() peut être appelé deux fois pour le même thread. Vous devez vous assurer que readCommand n'est pas appelé plusieurs fois et peut-être ne pas recommencer la lecture si elle est déjà en cours d'exécution. par exemple, vous pouvez synchroniser la méthode et vérifier readThread avant de commencer.

27
répondu Peter Lawrey 2011-09-06 06:58:24

un thread va lancer l'exception lors de l'appel de start si l'état du thread (tel que récupéré par Thread.currentThread().getState() est rien d'autre que NEW.

La source;

public synchronized void start() {
    /*
     * A zero status value corresponds to state "NEW".
     */
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
    group.add(this);
    start0();
    if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
}

cela signifie que votre thread est dans l'un des autres États, RUNNABLE,BLOCKED,WAITING,TIMED_WAITING ou TERMINATED.

vous pouvez avoir un regard sur l'état des threads via un dump de threads ou JConsole pour voir ce que le vôtre fait. Vous pouvez programmatically prendre une décharge de thread juste avant le appel à start en utilisant quelque chose comme tempus-fugit si cela peut aider.

mise à jour: en réponse à vos commentaires, si vous interrompez un thread qui dans votre cas, je suppose que le running drapeau à false, le thread sera toujours RUNNABLE. Pour "reprendre" travailler sur le thread (encore une fois, je suis en supposant que ce que vous voulez faire), vous pouvez modifier l' running encore un drapeau. Appel de start échouera parce que c'est déjà commencé. Vous pouvez également laisser le fil mourir sur interruption et puis créer une nouvelle instance d'un Thread et "démarrer" celui-là comme alternative.

20
répondu Toby 2012-06-12 18:09:28

consultez la page de documentation d'oracle à propos de Thread.démarrer()

public void start()

provoque l'exécution de ce thread; la machine virtuelle Java appelle la méthode run de ce thread.

le résultat est que deux threads tournent simultanément: le thread courant (qui retourne de l'appel à la méthode start) et l'autre thread (qui exécute sa méthode run).

il n'est jamais légal de lancer un thread plus d'une fois. En particulier, un thread ne peut pas être redémarré une fois qu'il a terminé l'exécution.

lancers: IllegalThreadStateException - si le thread était déjà démarré.

En environnement multi-thread, vous devez vous assurer que ci-dessus Thread est démarré exactement une fois. Si vous essayez start() sur un Thread, qui a déjà commencé, vous êtes lié à obtenir au-dessus de l'exception.

2
répondu Ravindra babu 2017-10-23 16:48:54

C'est très simple: il suffit d'utiliser run() au lieu de start().

1
répondu Roney Sampaio 2018-06-15 15:05:05

En fait, le processus d'appel est:

  • à Partir de la méthode main: contrôleur.principale(usbservice);

  • dans l'objet controller:

    @Override
    public void main(Object argv) {
        if(this.writer == null)
            this.writer = new CommandWriting(usbservice);
        if(this.reader == null)
            this.reader = new CommandReading(usbservice);
        reader.readCommand();
    }
    
  • Dans l'objet reader est la readCommand méthode.

alors, on ne l'appelle qu'une fois.

0
répondu Jose Hdez 2011-09-06 09:25:26