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?
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.
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.
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.
C'est très simple: il suffit d'utiliser run()
au lieu de start()
.
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.