java - reiniciar - método utilizado para comenzar la ejecución de un thread
¿Cómo puedo matar un hilo? sin usar stop(); (3)
La alternativa a detener la llamada es usar interrupción para indicar al hilo que desea que finalice lo que está haciendo. (Esto supone que el hilo que desea detener tiene un comportamiento correcto, si ignora InterruptedExceptions al comerlos inmediatamente después de que se lanzan y no verifica el estado interrumpido, entonces vuelve a usar stop ()).
Aquí hay un código que escribí como respuesta a una pregunta de subprocesamiento here , es un ejemplo de cómo funciona la interrupción de subprocesos:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Algunas cosas a tener en cuenta:
La interrupción hace que
sleep()
ywait()
se lancen inmediatamente; de lo contrario, se queda atascado esperando a que pase el tiempo de suspensión.Tenga en cuenta que no es necesario un distintivo booleano por separado.
El hilo que se detiene coopera comprobando el estado interrumpido y capturando InterruptedExceptions fuera del ciclo while (utilizándolo para salir del ciclo). La interrupción es un lugar donde está bien usar una excepción para el control de flujo, ese es el objetivo.
Establecer la interrupción en el subproceso actual en el bloque catch es técnicamente la mejor práctica pero es excesiva para este ejemplo, porque no hay nada más que necesite el indicador de interrupción establecido.
Algunas observaciones sobre el código publicado:
El ejemplo publicado está incompleto, pero poner una referencia al hilo actual en una variable de instancia parece una mala idea. Se inicializará en el hilo que está creando el objeto, no en el hilo que ejecuta el método de ejecución. Si la misma instancia ejecutable se ejecuta en más de un subproceso, la variable de instancia no reflejará el subproceso correcto la mayor parte del tiempo.
La comprobación de si el subproceso está activo necesariamente siempre dará como resultado verdadero (a menos que haya un error donde la variable de instancia
Thread#isAlive
estáThread#isAlive
referencia al subproceso incorrecto),Thread#isAlive
es falso solo después de que el subproceso ha terminado de ejecutarse, no devuelve falso solo porque ha sido interrumpido.La llamada
Thread#interrupted
dará como resultado la eliminación del indicador de interrupción, y no tiene sentido aquí, especialmente dado que el valor de retorno se descarta. El punto de llamar aThread#interrupted
es probar el estado de la bandera interrumpida y luego borrarlo, es un método conveniente utilizado por cosas que lanzanInterruptedException
.
Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
Normalmente, un hilo termina cuando se interrumpe . Entonces, ¿por qué no usar el booleano nativo ? Try isInterrupted() :
Thread t = new Thread(new Runnable(){
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Una buena forma de hacerlo sería usar un indicador booleano para señalar el hilo.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Cree una instancia de MyRunnable llamada myrunnable, envuélvala en una nueva instancia de Thread
e inicie la instancia. Cuando desee marcar el hilo para que pare, configure myrunnable.stopThread = true. De esta forma, no se detiene en el medio de algo, solo donde esperamos que se detenga.