java - termino - ¿Por qué no iniciar un hilo en el constructor? ¿Cómo terminar?
pasar parametros a un hilo java (4)
La segunda parte de esta pregunta es: ¿cómo si tengo un bucle ejecutándose en un hilo (el hilo de escucha del puerto serie) y escribo un comando de salida en mi segundo hilo? ¿Cómo puedo terminar el primer hilo?
Hazlo seguir hasta que se alcance una condición. Por ejemplo:
public void run() {
while ( !inputConsole.getCommand().equals("exit") ) {
//Do Something
Thread.sleep(1000); //put thread to sleep for 1 second
}
}
Estoy aprendiendo a usar hilos en Java. Y escribí una clase que implementa Runnable para ejecutar simultáneamente con otro hilo. El hilo principal se encarga de escuchar el puerto serie mientras que el segundo hilo manejará el envío de datos al mismo puerto.
public class MyNewThread implements Runnable {
Thread t;
MyNewThread() {
t = new Thread (this, "Data Thread");
t.start();
}
public void run() {
// New Thread code here
}
El primer hilo comienza el segundo así:
public class Main {
public static void main(String[] args) throws Exception{
new MyNewThread();
// First thread code there
}
}
Esto funciona, pero mi compilador muestra una advertencia que dice: es peligroso iniciar un nuevo hilo en el constructor. ¿Por qué es esto?
La segunda parte de esta pregunta es: ¿cómo si tengo un bucle ejecutándose en un hilo (el hilo de escucha del puerto serie) y escribo un comando de salida en mi segundo hilo? ¿Cómo puedo terminar el primer hilo? Gracias.
A su primera pregunta: iniciar un hilo en un constructor que pasa this
escapa this
. Eso significa que en realidad está dando una referencia a su objeto antes de que esté completamente construido. El hilo comenzará antes de que tu constructor termine. Esto puede dar lugar a todo tipo de comportamientos extraños.
A su segunda pregunta: no hay una forma aceptable de forzar que se detenga otro subproceso en Java, por lo que usaría una variable que el hilo verificaría para saber si debería detenerse o no. El otro hilo lo configuraría para indicar que el primer hilo se detendría. La variable debe ser volátil o todos los accesos deben estar sincronizados para garantizar una publicación adecuada. Aquí hay un código que sería algo como lo que quieres.
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
}
}
}
Todo lo que quiera crear e iniciar el hilo haría:
MyNewThread thread = new MyNewThread();
thread.start();
Todo lo que quiera detener el hilo haría:
thread.stop();
Echemos un vistazo a un ejemplo básico:
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
}
}
En este caso, se dice que MyClass.this escapa del constructor. Eso significa que el objeto está disponible para referencia pero todos sus campos que se están construyendo en el constructor pueden no crearse. Para llevar esto a otro nivel, ¿qué pasaría si b fuera final
? Esperaría que estuviera disponible, pero no está garantizado. Esto se conoce como objetos parcialmente construidos y es perfectamente legal en Java.
sobre la segunda pregunta, puede verificar si el segundo subproceso ha sido cancelado o no por el método isAlive
y, en caso afirmativo, utilice la palabra clave break
para desactivar el bucle para el primer subproceso, luego terminará si nada tiene que ver
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;
}
}
}