¿Cómo interrumpir correctamente un hilo?

Este artículo ha participado en la actividad "Ceremonia de creación de recién llegados", y hemos iniciado juntos el camino de la creación de Nuggets.

¿Cómo interrumpir correctamente un hilo?

1. Métodos proporcionados por hilos

  • interrumpir

Al llamar a este método, el sistema marcará el subproceso actual con un indicador de interrupción (verdadero), el valor predeterminado es falso, si otros subprocesos llaman a este método en el subproceso actual, significa que puede detener el subproceso actual y el subproceso actual también puede ignorarlo continuar

  • está interrumpido

Determine si el subproceso actual está interrumpido y realice el procesamiento relacionado de acuerdo con el bit indicador de interrupción del subproceso actual

  • Thread.interrupted() determina si el subproceso se interrumpe. Este método es un método estático. A diferencia de isInterrupted, el bit indicador de interrupción se restablecerá a falso después del juicio.
1.1 Interrumpir la operación a través del método proporcionado por Thread (recomendado)
 final Thread thread=new Thread("TestCustomisInterrupted"){
            @Override
            public void run() {
                super.run();
                //默认标志位 为false
                while (!isInterrupted()){
                    System.out.println(currentThread().getName()+"::::runing.......");
                }
                System.out.println("执行完成::::"+isInterrupted());  //true
            }
        };

        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();
复制代码

Lo anterior es un ejemplo relativamente simple, ¿qué pasa si hay un método de bloqueo en el cuerpo de ejecución del subproceso actual?

 final Thread thread=new Thread("TestCustomisInterrupted"){
            @Override
            public void run() {
                super.run();
                //默认标志位 为false
                while (!isInterrupted()){
                    try {
                        sleep(1000);
                        System.out.println(currentThread().getName()+"::::runing.......");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("执行完成::::"+isInterrupted());  //true
            }
        };

        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();

输入结果

TestCustomisInterrupted::::runing.......
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.example.socket.MyClass$1.run(MyClass.java:78)
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
复制代码

Se lanzará una excepción de interrupción y el indicador de interrupción se restablecerá a falso. El subproceso no se detendrá y continuará ejecutándose. Si desea que el programa continúe realizando la operación de interrupción, puede continuar configurando la operación de interrupción en La excepción.

Usando el método estático Thread.interrupted() para juzgar, si ocurre una interrupción, el bit indicador de interrupción se establecerá directamente en fasle

  final Thread thread=new Thread("TestCustomisInterrupted"){
            @Override
            public void run() {
                super.run();
                //默认标志位 为false
                while (!Thread.interrupted()){
                        System.out.println(currentThread().getName()+"::::runing.......");
                }
                System.out.println("执行完成::::"+isInterrupted());  //true
            }
        };

        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();

TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
执行完成::::false
复制代码

2. Terminar el hilo a través del campo personalizado de hilo

 class MyRunable implements Runnable{
            boolean isRun=true;

            public boolean isRun() {
                return isRun;
            }

            public void setRun(boolean run) {
                isRun = run;
            }

            @Override
            public void run() {
                while (isRun){
                    System.out.println("::::runing.......");
                }
                System.out.println("执行完成::::"+isRun);  //true
            }
        }
        MyRunable myRunable=new MyRunable();
       new Thread(myRunable).start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myRunable.setRun(false);


::::runing.......
::::runing.......
::::runing.......
::::runing.......
::::runing.......
执行完成::::false
复制代码

También puede usar una etiqueta personalizada para detener el hilo. ¿En qué se diferencia del método proporcionado por el hilo? Cuando hay un método de bloqueo en nuestra lógica de método de ejecución

        class Mythread extends Thread{
            boolean isRun=true;

            public boolean isRun() {
                return isRun;
            }

            public void setRun(boolean run) {
                isRun = run;
            }
            @Override
            public void run() {
                super.run();
                while (isRun()){
                    try {
                        Thread.sleep(4000);
                        System.out.println("::::runing.......");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("执行完成::::"+isRun());  //true
            }
        }

        Mythread mythread=new Mythread();
        mythread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mythread.setRun(false);

复制代码

Después de agregar el método de suspensión, se encuentra que el subproceso llamado cuando el subproceso está en suspensión mythread.setRun(false);no se detendrá inmediatamente y no se detendrá hasta que expire el tiempo de suspensión después de ejecutar el método de ejecución.

3. Use los métodos de detener, suspender y reanudar del hilo

Los tres métodos anteriores son proporcionados por subproceso, pero ahora están marcados como caducados y no se recomienda su uso, porque al usar los métodos anteriores, detener el sistema de subprocesos no liberará los recursos ocupados por el subproceso, porque no hay oportunidad ni tiempo. para que el subproceso libere recursos, lo que causará otros problemas, por lo que no se recomienda.

Supongo que te gusta

Origin juejin.im/post/7079289870526447646
Recomendado
Clasificación