El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos? me reí

Prefacio

El multihilo es básicamente un elemento de pregunta obligada en las entrevistas.Los entrevistadores generalmente comienzan con preguntas simples y luego profundizan en su conocimiento paso a paso.

Por ejemplo, a partir de lo que es un hilo, la diferencia entre un hilo y un proceso, hay varias formas de crear un hilo y hay varios estados para un hilo, y así sucesivamente.

A continuación, naturalmente conducirá a varios paquetes concurrentes de grupo de subprocesos, Lock, Synchronized y JUC. Luego conducirá a los principios de bajo nivel de AQS, CAS, JMM, JVM, etc., uno por uno.

En esta sección, no hablaremos de los demás, solo que hay varias formas de crear hilos.

¿Se siente muy simple? ¿No es solo ese tipo de cosas?

De hecho, no lo es. Sólo si le explicamos claramente al entrevistador y le agregamos nuestro propio entendimiento, podemos agregar puntos a la entrevista.

texto

En términos generales, tenemos los siguientes cuatro métodos más utilizados, el siguiente primero presenta su uso. Entonces, es más apropiado cómo responder a las preguntas del entrevistador durante la entrevista.

1. Heredar la clase Thread

Al heredar la clase Thread y reescribir su método de ejecución, podemos crear un hilo.

  • Primero defina una clase para heredar la clase Thread y anule el método de ejecución.
  • Luego crea este objeto de subclase y llama al método de inicio para iniciar el hilo.

El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos?  me reí

2. Implementar la interfaz Runnable

Al implementar Runnable e implementar el método de ejecución, también puede crear un hilo.

  • Primero defina una clase que implemente la interfaz Runnable e implemente el método de ejecución.
  • Luego cree un objeto de clase de implementación Runnable y páselo como destino al constructor de Thread
  • Finalmente, llame al método de inicio para iniciar el hilo.

El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos?  me reí

3. Implementar la interfaz invocable e implementarla en combinación con Future

  • Primero defina una clase de implementación invocable e implemente el método de llamada. El método de llamada tiene un valor de retorno.
  • Luego pase la clase de implementación invocable a través del método de construcción FutureTask.
  • Utilice FutureTask como destino de la clase Thread para crear un objeto Thread.
  • Obtenga el resultado de ejecución del hilo a través del método get de FutureTask.

El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos?  me reí

4. Crea subprocesos a través del grupo de subprocesos

Aquí usamos Executors que viene con el JDK para crear objetos de grupo de subprocesos.

  • Primero, defina una clase de implementación Runnable y anule el método de ejecución.
  • Luego, cree un grupo de subprocesos con un número fijo de subprocesos.
  • Finalmente, el objeto hilo se pasa a través del método de ejecución del objeto ExecutorService.

El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos?  me reí

¿Cuántas formas existen de crear hilos?

Entonces aquí viene la pregunta. He dado ejemplos de cuatro formas de crear hilos. ¿Significa que solo hay cuatro?

Primero veamos una explicación de la clase Thread en el código fuente de JDK, como se muestra en la siguiente figura.

El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos?  me reí

Hay dos formas de crear un nuevo hilo de ejecución.

Traducción: hay dos formas de crear un nuevo hilo de ejecución

Los dos métodos mencionados aquí corresponden a los dos primeros métodos que presentamos.

Sin embargo, encontraremos que estos dos métodos eventualmente llamarán al método Thread.start, y el método start eventualmente llamará al método run.

La diferencia es que en la forma de implementar la interfaz Runnable, se llama al método de ejecución de la clase Thread. Echemos un vistazo a su código fuente,

El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos?  me reí

De esta manera, el objeto de clase de implementación Runnable creado se asignará al objetivo y se ejecutará el método de ejecución del objetivo.

Mirando la forma de heredar la clase Thread, también necesitamos llamar al método de inicio de Thread para iniciar el hilo. Dado que la subclase anula el método de ejecución de la clase Thread, finalmente se ejecuta el método de ejecución de esta subclase.

Por tanto, también podemos decir lo mismo. En esencia, solo hay una forma de crear un hilo, que es construir una clase Thread (su subclase también se puede considerar una clase Thread).

Hay dos formas de construir la clase Thread, una es heredar la clase Thread y la otra es implementar la interfaz Runnable. Eventualmente creará objetos de la clase Thread (o sus subclases).

Veamos la forma de implementar Callable, combinando Future y FutureTask. Se puede encontrar que la clase Thread finalmente se construye a través de un nuevo Thread (tarea).

Finalmente, en el grupo de subprocesos, en realidad le entregamos la tarea de crear y administrar subprocesos al grupo de subprocesos. La creación de hilos se crea a través de la clase de fábrica de hilos DefaultThreadFactory (también puede personalizar la clase de fábrica). Veamos la implementación específica de esta clase de fábrica.

El entrevistador me preguntó: ¿Cuántas formas hay de crear hilos?  me reí

Establecerá algunos valores predeterminados para el hilo, como el nombre del hilo, la prioridad del hilo, el grupo de hilo, si es un hilo demonio, etc. Finalmente, el hilo se crea mediante el nuevo método Thread ().

Por tanto, en resumen. Al responder a esta pregunta, podemos decir que esencialmente solo hay una forma de crear un hilo, que es construir una clase de hilo . (Esta conclusión toma prestado de Java Concurrent Programming 78 Lectures-Xu Longxi)

idea personal

Sin embargo, aquí quiero plantear algunas preguntas sobre esta conclusión (si tiene opiniones diferentes, puede dejar un mensaje al final del artículo ~). . .

Personalmente, si quiere decir que hay 1, 2, 3 y 4 tipos, está bien. Lo importante es que debe poder establecer su base y decir sus diferencias y puntos en común. Habla bien, deja que el entrevistador te asienta con frecuencia. .

Es un poco descabellado decir que solo hay una forma de crear subprocesos mediante la construcción de la clase Thread. Porque, no importa si comienzas por cualquier medio, si quieres crear un hilo, definitivamente construirás la clase Thread al final. (Incluyendo los métodos anteriores, incluso a través de la reflexión, ¿no es también una nueva instancia al final?).

Entonces, si seguimos esta lógica, puedo decir que no importa cómo crear cualquier objeto, solo hay una forma de construir la clase Object. Esta conclusión parece un poco aburrida, porque es una tontería muy correcta.

Tome ArrayList como ejemplo, le pregunto cómo crear ArrayList de varias formas. El 80% de ustedes me dirán que luche lo que saben,

  1. A través del método de construcción,List list = new ArrayList();
  2. Por  Arrays.asList("a", "b");
  3. A través de la API Stream proporcionada por Java8, como List list = Stream.of("a", "b").collect(Collectors.toList());
  4. A través del paquete de jarra de terceros de guayaba,List list3 = Lists.newArrayList("a", "b");

Espere, solo cuatro se enumeran arriba. Ahora, te digo que solo hay una forma de crear una ArrayList, que es construir una clase ArrayList, no estás loco.

Es como, te pregunté cuántas formas hay de ir de Beijing a Shanghai.

Dice que puede tomar un automóvil, tren, tren, tren de alta velocidad o avión.

Eso no es correcto, tanto los trenes de alta velocidad como los trenes de alta velocidad pertenecen a los trenes, los coches y los trenes pertenecen a los coches, y los coches y los aviones pertenecen a los medios de transporte. De esta manera, solo hay una forma, que es tomar el transporte.

Esto no está bien. No necesito tomar el transporte. ¿No puedo caminar hasta allí? (Puedo teletransportarme con mis ojos, solo con tu piel ~).

La conclusión final es que solo hay un camino, es decir, puedes ir a Shanghai. Esto, esto, esto es una conclusión. . .

Así que personalmente creo que solo hay una forma de crear hilos.

Un buen ensayo técnico, casi escrito por mí en un ensayo argumentativo. . .

El benevolente ve al benevolente y el sabio ve la sabiduría.

Finalmente, echemos un vistazo a un tema muy interesante que vi en Internet.

Tema interesante

Pregunta: Una clase que implementa la interfaz Runnable ejecutará el método de ejecución predeterminado, luego juzgará que el objetivo no está vacío y finalmente ejecutará el método de ejecución implementado en la interfaz Runnable. Heredar la clase Thread ejecutará el método de ejecución reescrito. Entonces, ahora heredo la clase Thread e implemento la interfaz Runnable. El siguiente programa, ¿cuál debería ser la salida?

public class TestThread {
    public static void main(String[] args) {
        new Thread(()-> System.out.println("runnable")){
            @Override
            public void run() {
                System.out.println("Thread run");
            }
        }.start();
    }
}

Puede parecer desalentador a primera vista, qué tipo de operación es esta.

De hecho, si desensamblamos el código anterior, sabremos que este es un objeto de subclase que hereda la clase principal de Thread y anula el método de ejecución de la clase principal. Luego, en el objeto padre Thread, se pasa una clase de implementación de la interfaz Runnable en el método de construcción para implementar el método de ejecución.

Ahora que se ejecuta el método de inicio, inevitablemente buscará primero el método de ejecución en la subclase. Si lo encuentra, lo ejecutará directamente. El método de ejecución de la clase principal no se ejecutará, por lo que el resultado es: Ejecución del hilo.

Si se supone que la subclase no implementa el método de ejecución, buscará el método de ejecución en la clase principal, y el método de ejecución de la clase principal determinará si hay un Runnable pasado (es decir, si el objetivo está vacío) y ahora el objetivo no está vacío, por lo que Se ejecutará el método target.run y se imprimirá el resultado: ejecutable.

Entonces, el código anterior parece complicado, pero en realidad es muy simple. Al observar la esencia a través del fenómeno, encontraremos que no es más que investigar la relación de herencia padre-hijo de la clase, y la subclase anula el método de la clase padre y dará prioridad al método de anulación de subclase.

Combinado con hilos, si no está familiarizado con el mecanismo de funcionamiento del hilo, puede confundirse.

Supongo que te gusta

Origin blog.51cto.com/14957073/2544445
Recomendado
Clasificación