Escribí un hilo, está tardando demasiado tiempo en ejecutarse y parece que no está completamente terminado. Quiero detener el hilo con gracia. Alguna ayuda ?¿Cómo detener un hilo de Java con gracia?
Respuesta
El buena manera de hacerlo es tener la run()
de la rosca vigilado por una variable boolean
y ponerlo a true
desde el exterior cuando se desea detenerlo, algo así como:
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
Érase una vez un método stop()
existía pero como la documentación indica
Este método es inherentemente inseguro. Detener un hilo con Thread.stop hace que desbloquee todos los monitores que ha bloqueado (como consecuencia natural de la excepción ThreadDeath no verificada que se propaga por la pila). Si alguno de los objetos previamente protegidos por estos monitores se encontraba en un estado incoherente, los objetos dañados se vuelven visibles para otros hilos, lo que puede generar un comportamiento arbitrario.
Es por eso que usted debe tener un guardia ..
Haz un booleano volátil stop
en alguna parte. Luego, en el código que se ejecuta en el hilo, hacer regularmente
if (stop) // end gracefully by breaking out of loop or whatever
Para detener el hilo, fijado a stop
true
.
Creo que debe hacerlo manualmente de esta manera. Después de todo, solo el código que se ejecuta en el hilo tiene alguna idea de lo que es y no es gracioso.
Tenga en cuenta que sea necesario utilizar el bloqueo o hacer que el campo volátil para asegurarse de que el hilo de la lectura ve cambios con respecto al hilo de la escritura. –
@Jon Skeet: Sí, eso sería mejor. Por curiosidad, ¿cuánto tiempo se demoraría aproximadamente si el campo no es volátil? –
@Bart: en práctica, probablemente no mucho. En teoría, para siempre. –
Usted no debe matar a rosca de otro. Se considera un hábito bastante malo. Sin embargo, hay muchas formas. Puede usar la instrucción return
desde el método run
del hilo. O puede verificar si el hilo ya ha sido interrumpido y luego cancelará su trabajo. F.e. :
while (!isInterrupted()) {
// doStuff
}
El método de ejecución es nulo, no puede devolver nada. –
puede usar la declaración de devolución vacía con el tipo de devolución nula, el método terminará – Xorty
esto es similar a la primera respuesta, excepto que está utilizando return en lugar de simplemente dejar que el método run() salga. Y sí, solo puede usar return; y que saldrá de un método nulo – Richard
Es necesario enviar un mensaje de detención al hilo y el hilo en sí tiene que tomar medidas si el mensaje ha sido recibido. Esto es bastante fácil, si la acción de larga duración está dentro del bucle:
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
Como Jon Skeet comentó en mi respuesta, parada debe ser volátil –
I editado mi respuesta, pero voy a ir a buscar a cabo, por lo que se aplica aquí - en su respuesta, pensé, tenía que ser volátil sólo porque usted no mencionó una método y parecía que el campo 'stop' tenía que ser accedido directamente. –
me he preguntado acerca de la palabra clave volátil antes y (sin tratar de hacer publicidad de mi propia pregunta :)), aquí hay algunas respuestas en él: http://stackoverflow.com/questions/106591/do-you-ever- use-the-volátil-keyword-in-java – Richard
Lo malo de usar una bandera para detener el hilo es que si el hilo está esperando o dormir entonces usted tiene que esperar a que se terminar esperando/durmiendo. Si llama al método de interrupción en el subproceso, eso hará que la llamada de espera o de espera se cierre con una excepción interrumpida.
La interrupción de llamada() también establece una propiedad interrumpida que puede usar como indicador para comprobar si se cierra (en caso de que el hilo no esté esperando o durmiendo).
Puede escribir método run del hilo para que la InterruptedException es atrapado fuera de cualquier bucle lógica de la rosca está haciendo, o se puede detectar la excepción dentro del bucle y cerca de la llamada lanzar la excepción, estableciendo el indicador de interrupción dentro de la catch block para InterruptedException para que el hilo no pierda de vista el hecho de que fue interrumpido. El hilo interrumpido aún puede mantener el control y finalizar el procesamiento en sus propios términos.
Digamos que quiero escribir un subproceso de trabajo que funciona en incrementos, donde hay una pausa en el medio por alguna razón, y no quiero dejar el reposo para que el proceso se cierre sin hacer el trabajo restante para ese incremento , sólo lo quieren dejar de fumar si está en el medio incrementos:
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
Here is an answer to a similar question, including example code.
para un hilo para detener la misma, nadie parece haber mencionado (mal) uso de excepción:
abstract class SelfStoppingThread extends Thread {
@Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
Una subclase sólo tiene que anular doRun() normalmente como lo haría con un hilo, y llamar a stopSelf() cada vez que se siente como que quiere parar. OMI se siente más limpio que usar una bandera en un ciclo while.
- 1. Cierre con gracia un hilo
- 2. Cómo detener procesos largos de ejecución con gracia?
- 3. deteniendo con gracia un std :: hilo?
- 4. Detener un hilo en Java?
- 5. Detener un hilo
- 6. Cómo detener el bucle infinito en script bash con gracia?
- 7. ¿Cómo detener un hilo esperando en una operación de bloqueo de lectura en Java?
- 8. evitando con Gracia NullPointerException en Java
- 9. Interrumpir o detener un hilo que duerme
- 10. ¿Cómo puedo matar un hilo de otro hilo en Java?
- 11. ¿Cómo detener el proceso de Java con elegancia?
- 12. Cómo manejar con gracia la señal SIGKILL en Java
- 13. IntelliJ - detener un hilo durante la depuración
- 14. Terminar un subproceso con gracia sin utilizar TerminateThread()
- 15. Cómo detener el hilo asynctask en android?
- 16. cómo detener el hilo ASyncTask en android
- 17. Detener el hilo en python3
- 18. Detener un hilo después de un cierto período de tiempo
- 19. ¿Puedo detener un System.Threading.Timer
- 20. C# Threading - Cómo iniciar y detener un hilo
- 21. Cómo detener un hilo cuando se cierra mi aplicación winform
- 22. cómo detener un NSThread sub-hilo en iphone
- 23. Tomcat detener un hilo para evitar fugas de memoria potencial
- 24. ¿Cómo iniciar y detener un contenedor Tomcat con Java?
- 25. Java Detener servidor de rosca
- 26. Detener un hilo atascado en una llamada de bloqueo
- 27. ¿Puedo ejecutar un hilo dentro de un hilo en java?
- 28. Java ExecutorService pausa/reanudar un hilo específico
- 29. ¿Cómo reutilizar un hilo en Java?
- 30. ¿Cómo puedo depurar un hilo Java colgante?
Vea el comentario de Jon Skeet a la respuesta de Bart, se aplica también al suyo. –
Si el cambio "terminado" cambia mientras está haciendo su trabajo sucio, el hilo no terminará, entonces tiene que hacer una comprobación periódica, por ejemplo, con un ciclo de suspensión (sleep), algo que no se recomienda y le da un mal rendimiento, ¿es realmente este un buen enfoque? –
estamos hablando de dejar un hilo con gracia. Obligar a un hilo a dejar de fumar en medio de su trabajo sucio no es una manera elegante de hacerlo. Siempre debe esperar para la próxima iteración a menos que usted tiene una razón específica para interrumpirlo .. – Jack