Resuelva todas las preguntas de la entrevista del grupo de subprocesos de Java en cinco minutos

1. Por qué utilizar el grupo de subprocesos

  1. Reducir el consumo de recursos. Reduzca el consumo causado por la creación y destrucción de subprocesos reutilizando los subprocesos creados.

  2. Mejora la velocidad de respuesta. Cuando llega la tarea, la tarea se puede ejecutar inmediatamente sin esperar a que se cree el hilo.

  3. Mejorar la capacidad de administración de los subprocesos. El subproceso es un recurso escaso. Si se crea de forma ilimitada, no solo consumirá recursos del sistema, sino que también reducirá la estabilidad del sistema. El grupo de subprocesos se puede utilizar para asignación, ajuste y supervisión unificados.

2. Explicación detallada de siete parámetros de la clase de grupo de subprocesos ThreadPoolExecutor

parámetro Descripción
corePoolSize El número de subprocesos centrales, el número mínimo de subprocesos que mantiene el grupo de subprocesos
maximumPoolSize El número máximo de subprocesos mantenidos por el grupo de subprocesos
keepAliveTime Se destruirá el tiempo de inactividad más largo de los subprocesos distintos del subproceso principal del grupo de subprocesos y los subprocesos inactivos que superen este tiempo.
unidad La unidad de keepAliveTime, varios atributos estáticos en TimeUnit: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS
workQueue Cola de búfer de tareas utilizada por el grupo de subprocesos
threadFactory Fábrica de subprocesos, que se utiliza para crear subprocesos, generalmente utiliza el valor predeterminado
manipulador Estrategia de procesamiento del grupo de subprocesos para tareas rechazadas

Cuando la tarea del grupo de subprocesos no se puede procesar, se puede procesar a través de la estrategia especificada por el controlador.

ThreadPoolExecutor proporciona cuatro estrategias:

  1. ThreadPoolExecutor.AbortPolicy: abandona la tarea y lanza RejectedExecutionException ; también es el método de procesamiento predeterminado.
  2. ThreadPoolExecutor.DiscardPolicy: Descarte la tarea sin lanzar una excepción .
  3. ThreadPoolExecutor.DiscardOldestPolicy: Descarte la primera tarea en la cola y luego intente ejecutar la tarea nuevamente (repita este proceso)
  4. ThreadPoolExecutor.CallerRunsPolicy: la tarea es manejada por el hilo de llamada

El método de procesamiento se puede personalizar implementando la interfaz RejectedExecutionHandler.

Tres, ejecución de tareas de grupo de subprocesos

1. Agregar una tarea de ejecución

  • submit () Este método devuelve un objeto Future, que puede ejecutar un hilo con un valor de retorno; o ejecutar un hilo que desea cancelar en cualquier momento. El método get () del objeto Future obtiene el valor de retorno. La cancelación (verdadero / falso) del objeto Future cancela la tarea, devuelve falso si no se inició o se completó, y el parámetro indica si interrumpir el hilo en ejecución.
  • execute () no tiene valor de retorno.

2. Proceso de envío de tareas del grupo de subprocesos

2.1 Si el número de grupos de subprocesos es menor que corePoolSize en este momento, incluso si los subprocesos en el grupo de subprocesos están inactivos, se deben crear nuevos subprocesos para manejar las tareas agregadas.
2.2 Si el número de grupos de subprocesos es igual a corePoolSize en este momento, pero la cola del búfer workQueue no está llena , entonces la tarea se coloca en la cola del búfer.
2.3. Si el número en el grupo de subprocesos es mayor o igual que corePoolSize, la cola de búfer workQueue está llena y el número en el grupo de subprocesos es menor que maximumPoolSize, se crea un nuevo subproceso para procesar las tareas agregadas.
2.4 Si el número en el grupo de subprocesos es mayor que corePoolSize, la cola de búfer workQueue está llena y el número en el grupo de subprocesos es igual al maximumPoolSize, entonces la tarea es procesada por la estrategia especificada por el controlador .
2.5 Cuando el número de subprocesos en el grupo de subprocesos es mayor que corePoolSize, si el tiempo de inactividad de un subproceso excede keepAliveTime, el subproceso se terminará. De esta manera, el grupo de subprocesos puede ajustar dinámicamente el número de subprocesos en el grupo.

El resumen es: la prioridad del juicio de la tarea de procesamiento es el subproceso central corePoolSize, la cola de tareas workQueue y el subproceso máximo maximumPoolSize. Si los tres están llenos, use el controlador para procesar la tarea rechazada.

Nota:

  1. Cuando workQueue usa la cola de límite de ×××, el parámetro maximumPoolSize deja de tener sentido, como new LinkedBlockingQueue (), o new ArrayBlockingQueue (Integer.MAX_VALUE);
  2. Cuando se usa la cola SynchronousQueue, debido a que la cola no tiene capacidad, la tarea no se pondrá en cola. Si no hay un subproceso inactivo en el grupo de subprocesos, se creará un subproceso nuevo inmediatamente para recibir la tarea. MaximumPoolSize debe establecerse más grande.
  3. KeepAliveTime no tiene ningún efecto cuando el número de subprocesos principales y el número máximo de subprocesos son iguales.

3. El grupo de subprocesos está cerrado

3.1. Shutdown () no acepta nuevas tareas y procesará las tareas agregadas
3.2. ShutdownNow () no acepta nuevas tareas, no procesa las tareas agregadas e interrumpe las tareas que se están procesando

4. Introducción a las colas comunes

4.1. ArrayBlockingQueue: esta es una cola de bloqueo limitada con una capacidad fija implementada por una matriz .
4.2. SynchronousQueue: sin capacidad, los datos no se pueden almacenar en caché; cada puesta debe esperar una toma; cuando oferta (), si no hay otro hilo en poll () o take () devolverá falso.
4.3 LinkedBlockingQueue: Se trata de una cola de bloqueo predeterminada ××× implementada por una lista enlazada individualmente. LinkedBlockingQueue proporciona un constructor limitado opcional , y cuando no se especifica la capacidad, la capacidad predeterminada es Integer.MAX_VALUE .

Operación en cola:

método Descripción
agregar Agrega un yuansoil; si la cola está llena, lanza una excepción
retirar Elimina y devuelve el elemento al principio de la cola; si la cola está vacía, se lanza una excepción
oferta Agregue un elemento y devuelva verdadero; si la cola está llena, devuelva falso
encuesta Elimina y devuelve el elemento al principio de la cola; si la cola está vacía, devuelve nulo
poner Agrega un elemento; si la cola está llena, bloquea
llevar Eliminar y devolver el elemento al principio de la cola; si la cola está vacía, bloquear
elemento Devuelve el elemento al principio de la cola; si la cola está vacía, se lanza una excepción
ojeada Devuelve el elemento al principio de la cola; si la cola está vacía, devuelve nulo

5. Clase de fábrica de hilos de los ejecutores

1. Executors.newCachedThreadPool ();
Descripción: Crea un grupo de subprocesos almacenable en caché. Si la longitud del grupo de subprocesos excede el requisito de procesamiento, los subprocesos inactivos se pueden reciclar de manera flexible. Si no hay reciclaje, se pueden crear nuevos subprocesos.
Implementación interna: new ThreadPoolExecutor (0, Integer. MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue <runnable> ()); </runnable>

2. Executors.newFixedThreadPool (int);
Descripción: Cree un grupo de subprocesos de longitud fija, que puede controlar el número máximo de subprocesos simultáneos, y el exceso de subprocesos esperará en la cola.
Implementación interna: nuevo ThreadPoolExecutor (nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue <runnable> ()); </runnable>

3. Executors.newSingleThreadExecutor ();
Descripción: Crea un grupo de subprocesos de un solo subproceso, solo usará un solo subproceso de trabajo para realizar tareas, asegurando que todas las tareas se ejecuten en orden.
Implementación interna: nuevo ThreadPoolExecutor (1,1,0L, TimeUnit.MILLISECONDS, nuevo LinkedBlockingQueue <runnable> ()) </runnable>

4. Executors.newScheduledThreadPool (int);
Descripción: Cree un grupo de subprocesos de longitud fija para admitir el tiempo y la ejecución periódica de tareas.
Implementación interna: nuevo ScheduledThreadPoolExecutor (corePoolSize)

[Adjunto] Manual de desarrollo de Java de Alibaba para el uso de especificaciones de grupos de subprocesos

  1. [Obligatorio] Al crear un hilo o grupo de hilos, especifique un nombre de hilo significativo para facilitar el retroceso en caso de errores.
    Ejemplo positivo:

    public class TimerTaskThread extends Thread {
    public TimerTaskThread(){
        super.setName("TimerTaskThread"); 
        ...
    }
    }
  2. [Obligatorio] Los recursos de subprocesos se deben proporcionar a través del grupo de subprocesos y no se permite crear subprocesos explícitamente en la aplicación.
    Nota: La ventaja de utilizar el grupo de subprocesos es reducir el tiempo dedicado a crear y destruir subprocesos y la sobrecarga de los recursos del sistema, y ​​resolver
    el problema de la insuficiencia de recursos . Si no se utiliza la agrupación de subprocesos, puede hacer que el sistema cree una gran cantidad de subprocesos del mismo tipo y provocar
    el problema de quedarse sin memoria o "cambiar en exceso".

  3. [Obligatorio] No se permite crear grupos de subprocesos usando Ejecutores, pero se crean a través de ThreadPoolExecutor. Esta forma
    de procesamiento permite a los estudiantes escribir más claramente las reglas de funcionamiento del grupo de subprocesos y evitar el riesgo de agotamiento de recursos.

Explicación: Los inconvenientes de los objetos del grupo de subprocesos devueltos por los ejecutores son los siguientes:
1) FixedThreadPool y SingleThreadPool: la
longitud de la cola de solicitudes permitida es Integer.MAX_VALUE, que puede acumular una gran cantidad de solicitudes, lo que puede conducir a OOM.
2) CachedThreadPool y ScheduledThreadPool: El
número permitido de subprocesos que se creará es Integer.MAX_VALUE, que puede crear una gran cantidad de subprocesos, lo que lleva a OOM.

6. Resumen

ThreadPoolExecutor define diferentes tipos de grupos de subprocesos a través de varios parámetros principales, que son adecuados para diferentes escenarios de uso; entre ellos, cuando se envía la tarea, determinará corePoolSize, workQueque y maximumPoolSize en secuencia, y los diferentes estados se procesan de manera diferente.

Base de configuración de los parámetros básicos

1.1, el número de subprocesos centrales corePoolSize

El diseño de la cantidad de subprocesos centrales debe determinarse de acuerdo con el tiempo de procesamiento de la tarea y la cantidad de tareas generadas por segundo. Por ejemplo, se tarda 0,1 segundos en ejecutar una tarea y el sistema genera 100 tareas por segundo en 80% del tiempo. Entonces queremos procesar estas 100 tareas en 1 segundo, se requieren 10 subprocesos. En este momento, podemos diseñar el número de subprocesos centrales para que sea 10. La situación real en ese momento era imposible de ser tan promedio, entonces generalmente podemos diseñar de acuerdo con el principio 2080, es decir, de acuerdo con el porcentaje En el caso de 80, se diseña el número de hilos de núcleo, y el 20% restante se puede procesar con el número máximo de hilos.

1.2, la longitud de la cola de tareas (workQueue)

La longitud de la cola de tareas generalmente se diseña como la cantidad de subprocesos centrales / tiempo de ejecución de una sola tarea * 2 (tiempo máximo de espera de la tarea / s). Por ejemplo, en el escenario anterior, la cantidad de subprocesos principales está diseñada para ser 10, y el tiempo de ejecución de una sola tarea es 0,1, por lo que la longitud de la cola se puede diseñar en 200

1.3, el número máximo de subprocesos (maximumPoolSize)

El diseño del número máximo de subprocesos no solo debe referirse a la condición del número de subprocesos centrales, sino que también debe referirse al número máximo de tareas generadas por el sistema por segundo. Por ejemplo, en el entorno anterior, si el número máximo de tareas generadas por el sistema por segundo es 1000, entonces el número máximo de subprocesos = (número máximo de tareas-longitud de la cola de tareas) * el tiempo de ejecución de una sola tarea; ambos el número máximo de subprocesos = (1000-200 ) * 0.1 = 80; por supuesto, el número máximo de subprocesos también tiene mucho que ver con la configuración del hardware del servidor

 

Supongo que te gusta

Origin blog.csdn.net/qq_27828675/article/details/115357347
Recomendado
Clasificación