J'apprends à utiliser des threads en Java. Et j'ai écrit une classe qui implémente Runnable pour s'exécuter simultanément sur un autre thread. Le thread principal gère l'écoute du port série alors que le second thread gère l'envoi des données vers ce même port.
public class MyNewThread implements Runnable {
Thread t;
MyNewThread() {
t = new Thread (this, "Data Thread");
t.start();
}
public void run() {
// New Thread code here
}
Là, le premier thread commence le second comme ceci:
public class Main {
public static void main(String[] args) throws Exception{
new MyNewThread();
// First thread code there
}
}
Cela fonctionne mais mon compliant signale un avertissement disant: Il est dangereux de démarrer un nouveau thread dans le constructeur. Pourquoi est-ce?
La deuxième partie de cette question est: comment faire si j'ai une boucle en cours d'exécution dans un thread (le thread d'écoute du port série) et que je tape une commande de sortie dans mon deuxième thread. Comment terminer le premier thread? Merci.
À votre première question: démarrer un thread dans un constructeur en passant par this
échappe this
. Cela signifie que vous donnez réellement une référence à votre objet avant qu'il ne soit entièrement construit. Le thread démarrera avant la fin de votre constructeur. Cela peut entraîner toutes sortes de comportements étranges.
À votre deuxième question: il n'y a aucun moyen acceptable de forcer un autre thread à s'arrêter en Java, donc vous utiliseriez une variable que le thread vérifierait pour savoir s'il devrait s'arrêter ou non. L'autre thread le définirait pour indiquer que le premier thread s'arrêterait. La variable doit être volatile ou tous les accès doivent être synchronisés pour garantir une publication correcte. Voici du code qui ressemblerait à ce que vous voulez.
public class MyNewThread implements Runnable {
private final Thread t;
private volatile boolean shouldStop = false;
MyNewThread() {
t = new Thread (this, "Data Thread");
}
public void start() {
t.start();
}
public void stop() {
shouldStop = true;
}
public void run() {
while(!shouldStop)
{
// do stuff
}
}
}
Tout ce qui veut créer et démarrer le thread ferait:
MyNewThread thread = new MyNewThread();
thread.start();
Tout ce qui veut arrêter le fil ferait:
thread.stop();
Jetons un coup d'œil à un exemple de base:
class MyClass implements Runnable{
int a = 0;
String b = null;
public MyClass(){
new Thread(this).start();
b = "Foo";
}
public void run(){
a = b.length(); //can throw NullPointerException
}
}
Dans ce cas, le MyClass.this est censé échapper au constructeur. Cela signifie que l'objet est disponible pour référence, mais que tous ses champs en cours de construction dans le constructeur peuvent ne pas être créés. Pour amener cela à un autre niveau, si b était final
Vous vous attendriez à ce qu'il soit disponible mais ce n'est pas garanti. Ceci est connu comme un objet partiellement construit et est parfaitement légal en Java.
à propos de la deuxième question, vous pouvez vérifier si le deuxième thread a été terminé ou non par la méthode isAlive
et si oui, utilisez le mot clé break
pour désactiver le bouclage du premier thread, puis il sera terminé si rien ne doit faire
public class MyNewThread implements Runnable {
Thread t;
MyNewThread() {
t = new Thread (this, "Data Thread");
t.start();
}
public void run() {
reading code ................
// New Thread code here
}
public class Main {
public static void main(String[] args) throws Exception{
MyNewThread thread = new MyNewThread();
while(true)
{
listening code ...................
if(!thread.t.isAlive())
break;
}
}
}