Tencent Entrevistador: ¿Cómo detener un hilo conductor? Me veo cegado. . .

medios de tope que opera en un hilo antes de que la tarea de procesado dejó de hacer la tarea, que es abandonar la operación actual. Detener un hilo puede utilizar el método Thread.stop (), pero es mejor no usarlo. A pesar de que hace detener un hilo conductor, pero este método no es seguro, pero está obsoleta métodos. Hay java en la siguiente tres formas de terminar un hilo conductor:

  1. Uso señales de salida, las salidas de rosca normalmente, es decir, después de la finalización de las termina método run hilo.

  2. Uso método de terminación de parada forzada, pero no se recomienda este método, porque la parada y suspender y reanudar son los mismos que los métodos anticuados obsoletos.

  3. Utilice interrupción hilo método de interrupción.

1. No se puede dejar de hilo

método Uso efecto de interrupción () no es como para + declaración de la rotura que, detiene inmediatamente el bucle. Llamada de interrupción método consiste en golpear una señal de stop en el hilo actual, en realidad no detener el hilo.

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            System.out.println("i="+(i+1));
        }
    }
}

public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        try {
            Thread.sleep(2000);
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

salida:

...
i=499994
i=499995
i=499996
i=499997
i=499998
i=499999
i=500000

2. Pase a determinar si el estado de parada

Thread.java clase proporciona dos métodos:

  1. this.interrupted (): prueba si el hilo actual se ha interrumpido;

  2. this.isInterrupted (): Comprueba si este hilo se ha interrumpido;

Entonces, ¿qué diferencia hace la vista de estos dos métodos? Vamos a echar un vistazo al método this.interrupted () Interpretación: prueba si el hilo actual se ha interrumpido, el subproceso actual se refiere al método de hilo conductor this.interrupted ().

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            i++;
//            System.out.println("i="+(i+1));
        }
    }
}

public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        try {
            Thread.sleep(2000);
            thread.interrupt();

            System.out.println("stop 1??" + thread.interrupted());
            System.out.println("stop 2??" + thread.interrupted());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

El resultado:

stop 1??false
stop 2??false

Aunque clase Run.java código de llamada hilo objeto en la siguiente: thread.interrupt (), y su uso posterior

System.out.println("stop 1??" + thread.interrupted());
System.out.println("stop 2??" + thread.interrupted());

Para determinar si el objeto se representa por un hilo de rosca se detiene, pero la Vista de impresión Console, no impidió que el hilo, que también demostró explican método () interrumpido Para probar si el subproceso actual se ha interrumpido. El hilo actual es el principal, nunca se detuvo, por lo que el resultado impreso es de dos falsa.

Cómo hacer que el principal efecto de interrupción del hilo?

public class Run2 {
    public static void main(String args[]){
        Thread.currentThread().interrupt();
        System.out.println("stop 1??" + Thread.interrupted());
        System.out.println("stop 2??" + Thread.interrupted());

        System.out.println("End");
    }
}

Resultados de operación como sigue:

stop 1??true
stop 2??false
End

Métodos interrumpidas () realmente juzgar si el subproceso actual se detiene. Pero ¿por qué los dos primeros valor booleano es falso que? La explicación oficial de los métodos de documentación de ayuda interrumpidas: Comprueba si el subproceso actual se ha interrumpido. Estado de alarma del hilo se elimina por este método.  En otras palabras, si el método se llama dos veces en una fila, la segunda llamada devuelve falso.

El siguiente método vistazo a inInterrupted ().

public class Run3 {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        thread.interrupt();
        System.out.println("stop 1??" + thread.isInterrupted());
        System.out.println("stop 2??" + thread.isInterrupted());
    }
}

El resultado:

stop 1??true
stop 2??true

isInterrupted () y aclarado, por lo que imprimir dos cierto.

3. puede dejar de hilo - Excepción Ley

Con los conocimientos adquiridos en el punto anterior, el hilo se puede utilizar para los estados para determinar lo que se detiene el hilo, si se detiene, entonces el código detrás ya no puede funcionar:

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            if(this.interrupted()) {
                System.out.println("线程已经终止, for循环不再执行");
                break;
            }
            System.out.println("i="+(i+1));
        }
    }
}

public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        try {
            Thread.sleep(2000);
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

El resultado:

...
i=202053
i=202054
i=202055
i=202056
线程已经终止, for循环不再执行

Aunque el ejemplo anterior para detener el hilo, pero si existe la siguiente declaración de declaración, seguirá funcionando. Vea los siguientes ejemplos:

public class MyThread extends Thread {
    public void run(){
        super.run();
        for(int i=0; i<500000; i++){
            if(this.interrupted()) {
                System.out.println("线程已经终止, for循环不再执行");
                break;
            }
            System.out.println("i="+(i+1));
        }

        System.out.println("这是for循环外面的语句,也会被执行");
    }
}

Uso Run.java resultados de la ejecución son:

...
i=180136
i=180137
i=180138
i=180139
线程已经终止, for循环不再执行
这是for循环外面的语句,也会被执行

¿Cómo resolver el problema declaraciones siguen ejecutarlo? Mira el código de actualización:

public class MyThread extends Thread {
    public void run(){
        super.run();
        try {
            for(int i=0; i<500000; i++){
                if(this.interrupted()) {
                    System.out.println("线程已经终止, for循环不再执行");
                        throw new InterruptedException();
                }
                System.out.println("i="+(i+1));
            }

            System.out.println("这是for循环外面的语句,也会被执行");
        } catch (InterruptedException e) {
            System.out.println("进入MyThread.java类中的catch了。。。");
            e.printStackTrace();
        }
    }
}

resultados operativos uso Run.java son los siguientes:

...
i=203798
i=203799
i=203800
线程已经终止, for循环不再执行
进入MyThread.java类中的catch了。。。
java.lang.InterruptedException
 at thread.MyThread.run(MyThread.java:13)

4. Detener el dormir

Si el hilo para detener el hilo en el estado de sueño (), ¿cuál sería el efecto?

public class MyThread extends Thread {
    public void run(){
        super.run();

        try {
            System.out.println("线程开始。。。");
            Thread.sleep(200000);
            System.out.println("线程结束。");
        } catch (InterruptedException e) {
            System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());
            e.printStackTrace();
        }

    }
}

Los resultados usando Run.java se están ejecutando:

线程开始。。。
在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at thread.MyThread.run(MyThread.java:12)

A partir de los resultados del punto de vista de la impresión, si se detiene un hilo en un estado de suspensión, entrará en la sentencia catch, y borra el valor de estado de parada, por lo que es un falso.

Antes de que una prueba es el sueño y luego usar la interrupción () para detener, en oposición a la operación debe prestar atención al proceso de aprendizaje:

public class MyThread extends Thread {
    public void run(){
        super.run();
        try {
            System.out.println("线程开始。。。");
            for(int i=0; i<10000; i++){
                System.out.println("i=" + i);
            }
            Thread.sleep(200000);
            System.out.println("线程结束。");
        } catch (InterruptedException e) {
             System.out.println("先停止,再遇到sleep,进入catch异常");
            e.printStackTrace();
        }

    }
}

public class Run {
    public static void main(String args[]){
        Thread thread = new MyThread();
        thread.start();
        thread.interrupt();
    }
}

El resultado:

i=9998
i=9999
先停止,再遇到sleep,进入catch异常
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at thread.MyThread.run(MyThread.java:15)

5. Ser capaz de detener la violencia, detener el hilo ---

Utilizando el método stop () deja el hilo es muy violenta.

public class MyThread extends Thread {
    private int i = 0;
    public void run(){
        super.run();
        try {
            while (true){
                System.out.println("i=" + i);
                i++;
                Thread.sleep(200);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Run {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new MyThread();
        thread.start();
        Thread.sleep(2000);
        thread.stop();
    }
}

El resultado:

i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9

Process finished with exit code 0

6. Método de parada () con el java.lang.ThreadDeath excepción

Java.lang.ThreadDeath arrojará una excepción cuando se llama al método stop (), pero en circunstancias normales, esta excepción no necesita explícitamente captura.

public class MyThread extends Thread {
    private int i = 0;
    public void run(){
        super.run();
        try {
            this.stop();
        } catch (ThreadDeath e) {
            System.out.println("进入异常catch");
            e.printStackTrace();
        }
    }
}

public class Run {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new MyThread();
        thread.start();
    }
}

método stop () y sin efecto, como para forzar el hilo para detener algunos de los trabajos tiene el potencial para limpiar la propiedad no puede ser completado. Otro caso es el de desbloqueo de un objeto bloqueado, lo que resulta en el procesamiento de los datos no están sincronizados, los problemas de datos inconsistentes.

7. Soltar el bloqueo de las consecuencias adversas

Utilizar stop () para liberar el bloqueo hará que los resultados hasta la incoherencia de datos. Si esto sucede, los datos de los programas de procesamiento, no se pueden dañar, lo que lleva a un proceso de ejecución del programa errónea, debemos prestar especial atención a:

public class SynchronizedObject {
    private String name = "a";
    private String password = "aa";

    public synchronized void printString(String name, String password){
        try {
            this.name = name;
            Thread.sleep(100000);
            this.password = password;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

public class MyThread extends Thread {
    private SynchronizedObject synchronizedObject;
    public MyThread(SynchronizedObject synchronizedObject){
        this.synchronizedObject = synchronizedObject;
    }

    public void run(){
        synchronizedObject.printString("b", "bb");
    }
}

public class Run {
    public static void main(String args[]) throws InterruptedException {
        SynchronizedObject synchronizedObject = new SynchronizedObject();
        Thread thread = new MyThread(synchronizedObject);
        thread.start();
        Thread.sleep(500);
        thread.stop();
        System.out.println(synchronizedObject.getName() + "  " + synchronizedObject.getPassword());
    }
}

salida:

b  aa

Dado que el método stop () y están marcados como "expirado / no válido" en la forma de JDK, es obvio que tiene un defecto en la función, no se recomienda el uso del método de parada () en las hojas del programa.

8. El uso del hilo bloqueo de retroceso

La interrupción método () mediante la combinación de regreso se puede lograr el efecto de parar el hilo:

public class MyThread extends Thread {
    public void run(){
        while (true){
            if(this.isInterrupted()){
                System.out.println("线程被停止了!");
                return;
            }
            System.out.println("Time: " + System.currentTimeMillis());
        }
    }
}

public class Run {
    public static void main(String args[]) throws InterruptedException {
        Thread thread = new MyThread();
        thread.start();
        Thread.sleep(2000);
        thread.interrupt();
    }
}

salida:

...
Time: 1467072288503
Time: 1467072288503
Time: 1467072288503
线程被停止了!

Sin embargo, se recomienda el uso de "una excepción" para lograr el hilo de parada, porque también se puede arrojar una excepción en el bloque catch, el hilo para detener el evento de difusión.

Publicado 50 artículos originales · ganado elogios 1706 · Vistas 2,22 millones +

Supongo que te gusta

Origin blog.csdn.net/zl1zl2zl3/article/details/105326795
Recomendado
Clasificación