Inicio de subprocesos y terminación segura

1. Inicio del hilo

Hay dos formas de iniciar un hilo, a saber, heredar la clase Thread y reescribir la interfaz Runable, de la siguiente manera:
inserte la descripción de la imagen aquí


1.1 、 Hilo

Con respecto a la creación de subprocesos por Thread, la función de creación de subprocesos en subprocesos múltiples de Java ya se ha introducido, por lo que no entraré en detalles aquí.


1.2 、 Ejecutable

En realidad, no existe una diferencia esencial entre Runnable y Thread, que es la diferencia entre interfaz y clase. Reescribir Runnbale aún necesita iniciar el hilo a través de Thread.


En uso, debido a que Java no permite la herencia múltiple, Runnable puede evitar los problemas causados ​​por la limitación de la herencia única.


1.3、Invocable

Dado que la interfaz Runnable no tiene valor de retorno, si se requiere un valor de retorno en algunos escenarios, entonces se debe utilizar la interfaz Callable.

public class App {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
        new Thread(futureTask).start();
        System.out.println(futureTask.get());
    }
}

class MyCallable implements Callable<String> {
    
    
    @Override
    public String call() throws Exception {
    
    
        return "success";
    }
}

Se ejecuta con la ayuda de FutureTaskla clase, y la clase FutureTask implementa las interfaces Future y Runnable al mismo tiempo, por lo que puede ser ejecutado por subprocesos como Runnable y también puede usarse como Future para obtener el valor de retorno de un invocable.
inserte la descripción de la imagen aquí

Cabe señalar que al obtener el valor de retorno FutureTask.get()se utiliza un método de bloqueo, una vez que se llama a este método, el código posterior se bloqueará y la ejecución solo podrá continuar después de que se ejecute el método invocable.


En segundo lugar, la suspensión del hilo.

A menudo puede ser necesario detener un hilo. suspend()Hay , y otros métodos en la API de Java , y sus funciones son suspender el hilo resume(), reanudar la ejecución del hilo y finalizar el hilo.stop()
inserte la descripción de la imagen aquí

Sin embargo, se descubre que estos tres métodos ya no se recomiendan, porque los tres métodos realizan operaciones inmediatas en nuestros subprocesos. Por ejemplo, los métodos stop()detendrán suspend()y suspenderán inmediatamente nuestros subprocesos, pero los recursos en los subprocesos no se liberarán. puede causar un problema de bloqueo del programa.


2.1, métodos de interrupción () e isInterrupted ()

Un hilo no debe ser interrumpido o detenido por la fuerza por otros hilos, sino que debe ser detenido por el propio hilo. Por lo tanto, puede usar interrupt()el método para notificar al subproceso que debe interrumpirse, pero el subproceso notificado debe manejar si interrumpir o continuar ejecutándose.


Llamar al método de interrupción() solo establecerá el indicador de interrupción del hilo en verdadero, no forzará una interrupción. Al mismo tiempo, Java también proporciona un método para consultar si el hilo está interrumpido isInterrupted()y un método estático Thread.interrupted(). La diferencia es que el método estático establecerá el estado en falso después de consultar el estado interrumpido de nuestro hilo.
inserte la descripción de la imagen aquí

En las siguientes pruebas, se puede encontrar que el método estático Thread.interrupted () que consulta si el hilo está interrumpido cambia el indicador de interrupción a falso. Además, el hilo principal se usa directamente para verlo aquí. Si un Se crea un nuevo hilo para realizar pruebas. Primero debe iniciar el hilo y mantenerlo en ejecución; de lo contrario, la consulta debe ser falsa.
inserte la descripción de la imagen aquí


Además, no se recomienda personalizar un indicador de cancelación para suspender la ejecución del hilo. Porque cuando hay bloqueo en el método run(), no se puede detectar el indicador de cancelación personalizado y el hilo debe regresar de la llamada de bloqueo antes de verificar el indicador de cancelación.


2.2, excepción de excepción interrumpida

Si un subproceso está en un estado bloqueado (por ejemplo, el subproceso llama a thread.sleep(), thread.join(), thread.wait(), etc.) y se llama al método de interrupción para interrumpir la operación, se produce una excepción InterruptedException. Se lanzará, pero Inmediatamente después de que se lanza una excepción, el bit de indicador de interrupción del hilo se borra, es decir, se restablece a falso.
inserte la descripción de la imagen aquí


Entonces estamos en la excepción InterruptedException, si confirmamos que el hilo necesita ser interrumpido, aquí debemos configurar nuestro indicador de interrupción nuevamente.
inserte la descripción de la imagen aquí


2.3 、 tarea futura

El FutureTask que implementa la interfaz Future también nos proporciona otros métodos de interrupción, como por ejemplo cancel()enviar una señal de interrupción.


Además, la clase FutureTask también proporciona isDone()y isCancelled(), que se utilizan para juzgar si la tarea se completa y si se cancela, respectivamente.
inserte la descripción de la imagen aquí

  • cancelar (booleano): la tarea se cancela y devuelve verdadero; de lo contrario, falso
    1. cancelar (verdadero): interrumpirá la tarea en ejecución
    2. cancelar (falso): no interrumpirá las tareas que ya se están ejecutando
  • isDone (): si la tarea se completa, si finaliza normalmente, finaliza de forma anormal o se cancela, devuelve verdadero
  • isCancelled(): si la tarea se canceló antes de completarse

Supongo que te gusta

Origin blog.csdn.net/rockvine/article/details/124972509
Recomendado
Clasificación