Mecanismo de interrupción de la programación concurrente JUC

Tabla de contenido

1. Mecanismo de interrupción

1.1 Principio de interrupción

1.2 Método de interrupción

1.2.1 método interrupción()

 1.2.2 Método isInterrupted()

1.2.3 Método Thread.interrupted()

1.3 Manejar correctamente las interrupciones

1.4 Dejar de interrumpir subprocesos en ejecución

1.4.1 volátil

1.4.2 Clases atómicas


1. Mecanismo de interrupción

En la programación concurrente, la ejecución de un hilo puede ser interrumpida por otro hilo, esta interrupción se llama "interrupción". La interrupción es un mecanismo de comunicación entre subprocesos que permite que un subproceso notifique a otro subproceso, solicitándole que detenga su trabajo actual y realice algunas otras operaciones. El mecanismo de interrupción en JUC se interrupt()implementa a través de métodos.

1.1 Principio de interrupción

La interrupción se logra a través del bit indicador de interrupción del subproceso. Cada subproceso de Java tiene un indicador de interrupción booleano asociado. Cuando un subproceso llama interrupt()a un método, establece el bit indicador de interrupción del subproceso de destino en true, lo que indica que el subproceso ha sido interrumpido. El subproceso interrumpido puede descubrir la solicitud de interrupción comprobando su propio estado de interrupción.

1.2 Método de interrupción

1.2.1  interrupt()Método

interrupt()Los métodos son Threadmétodos de instancia de una clase que se utilizan para interrumpir el subproceso actual o especificar un subproceso de destino. Se declara de la siguiente manera:

public void interrupt()

 Llamar interrupt()al método establecerá el bit indicador de interrupción del subproceso de destino en true. Si el subproceso de destino está en un estado bloqueado (por ejemplo, llamando a métodos como sleep(), wait(), join()etc.), lanzará inmediatamente InterruptedExceptionuna excepción y regresará del estado bloqueado. Después de que el subproceso se interrumpe en el estado bloqueado y InterruptedExceptionse lanza una excepción, debemos restaurar el estado interrumpido. Esto se debe a que después de que se lanza la excepción, el indicador de interrupción se borrará.Si queremos que el código posterior detecte el estado de interrupción correctamente, debemos configurar manualmente el indicador de interrupción nuevamente.

catch (InterruptedException e) {
    // 恢复中断状态
    Thread.currentThread().interrupt();
}

 1.2.2   isInterrupted()Método

isInterrupted()method es Threadun método de instancia de la clase que se utiliza para consultar el estado de interrupción del subproceso actual. Se declara de la siguiente manera:

public boolean isInterrupted()

 El isInterrupted()método de llamada devolverá el bit indicador de interrupción del hilo actual. Tenga en cuenta que llamar a este método no borrará el indicador de interrupción.

1.2.3   Thread.interrupted()Método

Thread.interrupted()El método es Threadun método estático de la clase, que se utiliza para consultar el estado de interrupción del subproceso actual y borrar el bit indicador de interrupción. Se declara de la siguiente manera:

public static boolean interrupted()

El Thread.interrupted()método de llamada devuelve el estado de interrupción del subproceso actual y restablece el bit indicador de interrupción del subproceso actual a false.

1.3 Manejar correctamente las interrupciones

En el punto clave de la ejecución del subproceso, debemos verificar el estado de interrupción del subproceso y dar la respuesta correspondiente según la situación. Por ejemplo, al ejecutar una tarea en un ciclo, podemos usar isInterrupted()el método para verificar el estado de interrupción, y cuando encontramos que el hilo se ha interrumpido, podemos terminar el ciclo y salir del hilo a tiempo.

public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        // 执行任务...
    }
}

 A veces pasamos el bit indicador de interrupción a otros métodos u objetos.Después de procesar la lógica de interrupción, debemos borrar el estado de interrupción para no afectar los juicios de interrupción posteriores. El método se puede utilizar Thread.interrupted()para borrar el bit indicador de interrupción.

 Thread th = new Thread(() -> {
           while (!Thread.interrupted()){
               System.out.println(Thread.currentThread().getName());
               Thread.currentThread().interrupt();
           }
        }, "th");
        th.start();

1.4 Dejar de interrumpir subprocesos en ejecución

1.4.1 volátil

volatileEs una palabra clave en Java, utilizada para declarar variables. Su función principal es asegurar que volatilela variable modificada sea visible para todos los hilos, es decir, cada vez que volatilese lea la variable, se obtendrá el último valor directamente de la memoria principal en lugar de utilizar el valor de caché local del hilo. En un entorno de subprocesos múltiples, cuando un subproceso modifica volatileel valor de la variable modificada, el valor se actualizará en la memoria principal inmediatamente, y se notificará a otros subprocesos, y otros subprocesos verán el valor más reciente cuando lean la variable. Esto asegura que las modificaciones a la variable sean visibles para todos los subprocesos. volatileTambién puede evitar la reorganización de las instrucciones y garantizar que volatilelas operaciones de lectura y escritura de las variables modificadas estén en orden y que no haya resultados inesperados.

public class Test {

    private static volatile boolean key=false;
    public static void main(String[] args) throws InterruptedException {
             new Thread(()->{
                 while (true){
                     if(key){
                         System.out.println(Thread.currentThread().getName()+ "终止");
                         break;
                     }
                     System.out.println(Thread.currentThread().getName()+" 执行");
                 }
             }).start();
             
             new Thread(()->{
                 key=true;
             }).start();
    }
}

1.4.2 Clases atómicas

Las clases atómicas son un conjunto de clases de herramientas proporcionadas por JUC para implementar operaciones atómicas, que garantizan la atomicidad en operaciones específicas. La clase atómica implementa operaciones atómicas a través del algoritmo CAS (Comparar e intercambiar) CAS es una tecnología de bloqueo optimista que puede implementar operaciones simultáneas seguras para subprocesos sin usar bloqueos.

Las clases atómicas comúnmente utilizadas incluyen: AtomicInteger, AtomicLong, AtomicBooleanetc.

public class Test {

    private static AtomicBoolean atomicBoolean=new AtomicBoolean(false);
    public static void main(String[] args) throws InterruptedException {
             new Thread(()->{
                 while (true){
                     if(atomicBoolean.get()){
                         System.out.println(Thread.currentThread().getName()+ "终止");
                         break;
                     }
                     System.out.println(Thread.currentThread().getName()+" 执行");
                 }
             }).start();

             new Thread(()->{
                atomicBoolean.set(true);
             }).start();
    }
}

El tercer caso es usar el método de interrupción presentado al principio del artículo. omitido aquí.

Supongo que te gusta

Origin blog.csdn.net/qq_43649937/article/details/131996215
Recomendado
Clasificación