[Subprocesos múltiples] —— grupo de subprocesos

1. ¿Qué es un grupo de subprocesos y qué son los grupos de subprocesos (creación)?

El grupo de subprocesos consiste en colocar varios objetos de subprocesos en un contenedor por adelantado. Cuando lo usa, no necesita usar un subproceso nuevo, simplemente
vaya al grupo para obtener el subproceso directamente, lo que ahorra el tiempo de crear subprocesos y mejora la eficiencia de ejecución del código.

Los métodos estáticos para generar una variedad de grupos de subprocesos diferentes se proporcionan en la clase java.uti.concurrent./executors del JDK.

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);
ScheduledExecutorService newScheduledThreadPool =
Executors.newScheduledThreadPool(4);
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

Luego llame a su método de ejecución. Las capas inferiores de estos cuatro grupos de subprocesos están implementadas por el objeto ThreadPoolExecutor. El manual de especificación de Ali estipula que ThreadPoolExecutor personaliza
el grupo de subprocesos y el desarrollo real también es el mismo.

(1) nuevoCachedThreadPool

Cree un grupo de subprocesos almacenable en caché. Si la longitud del grupo de subprocesos excede las necesidades de procesamiento, los subprocesos inactivos se pueden reciclar de manera flexible. Si
no hay reciclaje, se crearán nuevos subprocesos. Las características de este tipo de grupo de subprocesos son:
casi no hay límite para la cantidad de subprocesos de trabajo creados (de hecho, hay un límite, el número es Integer.
MAX_VALUE), por lo que los subprocesos se pueden agregar al grupo de subprocesos de manera flexible. .
Si no se envía ninguna tarea al grupo de subprocesos durante un tiempo prolongado, es decir, si el subproceso de trabajo está inactivo durante un tiempo específico (
1 minuto de forma predeterminada), el subproceso de trabajo finalizará automáticamente. Después de la terminación, si envía una nueva tarea, el
grupo de subprocesos recreará un subproceso de trabajo.
Al utilizar CachedThreadPool, debe prestar atención a controlar la cantidad de tareas; de lo contrario, debido a una gran cantidad de subprocesos que
se ejecutan al mismo tiempo, es probable que cause una parálisis del sistema.

(2) nuevoFixedThreadPool

Cree un grupo de subprocesos con el número especificado de subprocesos de trabajo. Se crea un subproceso de trabajo cada vez que se envía una tarea y, si
el número de subprocesos de trabajo alcanza el número máximo inicial del grupo de subprocesos, la tarea enviada se almacena en la cola del grupo.
FixThreadPool es un grupo de subprocesos típico y excelente, que tiene las
ventajas de mejorar la eficiencia del programa y ahorrar la sobrecarga de crear subprocesos. Sin embargo, cuando el grupo de subprocesos está inactivo, es decir, cuando no hay tareas ejecutables en el grupo de subprocesos
, no liberará el subproceso de trabajo y también ocupará ciertos recursos del sistema.

(3) nuevoSingleThreadExecutor

Cree un ejecutor de un solo subproceso, es decir, cree solo un subproceso de trabajo único para ejecutar tareas, y solo utilizará
el único subproceso de trabajo para ejecutar tareas, asegurando que todas las tareas se ejecuten en el orden especificado (FIFO, LIFO, prioridad)
. Si este hilo finaliza de forma anormal, otro tomará su lugar, garantizando la ejecución secuencial. La característica más importante de un único subproceso de trabajo es que puede garantizar que las tareas se ejecuten secuencialmente y que no habrá varios subprocesos activos
en un momento dado .

(4) nuevoScheduleThreadPool

Cree un grupo de subprocesos de longitud fija y admita la sincronización y la ejecución periódica de tareas. Por ejemplo, retrasar la ejecución durante 3 segundos
.

2. ¿Por qué utilizar un grupo de subprocesos?

(1) El trabajo del grupo de subprocesos es principalmente controlar el número de subprocesos en ejecución. Durante el procesamiento, las tareas se colocan en la cola y luego estas tareas se inician
después de que se crean los subprocesos. Si el número de subprocesos excede el máximo número, los subprocesos sobrantes esperan en la cola
. Espere a que otros subprocesos terminen de ejecutarse y luego saque la tarea de la cola para su ejecución.

(2) Características principales: reutilización de subprocesos, controlar el número máximo de concurrencia: gestionar subprocesos.
Primero: reducir el consumo de recursos. Reduzca el costo de creación y destrucción de subprocesos reutilizando los subprocesos creados
.
Segundo: mejorar la velocidad de respuesta. Cuando llega una tarea, la tarea se puede ejecutar inmediatamente sin esperar a que se cree el hilo
.
Tercero: mejorar la capacidad de gestión de subprocesos. El subproceso es un recurso escaso. Si se crea sin límite, no solo consumirá
recursos del sistema, sino que también reducirá la estabilidad del sistema. El uso del grupo de subprocesos se puede utilizar para asignación, ajuste y monitoreo unificados.

3. El principio de funcionamiento subyacente del grupo de subprocesos.

inserte la descripción de la imagen aquí

  • (1) Paso 1: cuando se crea el grupo de subprocesos por primera vez, no hay subprocesos en él y no se crearán subprocesos hasta que llegue una tarea
    . Por supuesto, también puede llamar al
    método prestartAllCoreThreads() o prestartCoreThread() para crear previamente subprocesos corePoolSize
  • (2) Paso 2: al llamar a ejecutar () para enviar una tarea, si el número actual de subprocesos de trabajo
    <corePoolSize, cree directamente un nuevo subproceso para ejecutar la tarea
  • (3) Paso 3: si la cantidad de subprocesos de trabajo> = corePoolSize en ese momento, la tarea se almacenará en caché en la cola de tareas
  • (4) Paso 4: si la cola está llena y el número de subprocesos de trabajo en el grupo de subprocesos <maximumPoolSize,
    aún se creará un subproceso para ejecutar esta tarea
  • (5) Paso 5: si la cola está llena y los subprocesos en el grupo de subprocesos han alcanzado el tamaño máximo de grupo, la
    política de rechazo se ejecutará en este momento. La política predeterminada del grupo de subprocesos JAVA es AbortPolicy, es decir,
    una RejectedExecutionException ser arrojado

4. ¿Qué parámetros tiene el objeto ThreadPoolExecutor? ¿Cómo establecer la cantidad de subprocesos principales y la cantidad máxima de subprocesos? ¿Cuáles son las estrategias de negación?

En primer lugar, todos sabemos que existen 7 parámetros:

1) corePoolSize: el número de subprocesos centrales,

Hay una configuración relacionada con él en ThreadPoolExecutor: enableCoreThreadTimeOut (el valor predeterminado
es falso). Cuando enableCoreThreadTimeOut es falso, el subproceso central siempre sobrevivirá,
incluso si siempre está inactivo. Y cuando enableCoreThreadTimeOut es verdadero, el subproceso central
se reciclará cuando el tiempo de inactividad exceda keepAliveTime.

(2) MaximumPoolSize: número máximo de subprocesos

El número máximo de subprocesos que puede contener el grupo de subprocesos. Cuando el número de subprocesos en el grupo de subprocesos alcanza el máximo, se
adoptará la estrategia de rechazo para agregar tareas en este momento. La estrategia de rechazo predeterminada es generar un error de tiempo de ejecución
(RejectedExecutionException ). Vale la pena mencionar que cuando la cola de trabajo utilizada para la inicialización es
LinkedBlockingDeque, este valor no será válido.

(3) keepAliveTime: tiempo de supervivencia,

Cuando el tiempo de inactividad no central excede este tiempo, se reciclará y el hecho de que el subproceso central inactivo se recicle se verá afectado por
enableCoreThreadTimeOut.

(4) unidad: la unidad de keepAliveTime.

(5) workQueue: cola de tareas

Hay tres colas de uso común, a saber, SynchronousQueue, LinkedBlockingDeque (cola ilimitada
) y ArrayBlockingQueue (cola limitada).

(6) threadFactory: fábrica de hilos,

ThreadFactory es una interfaz utilizada para crear trabajadores. Algunas propiedades del hilo
se pueden personalizar a través de la fábrica de hilos. De forma predeterminada, se crea un nuevo hilo directamente.

(7) RejectedExecutionHandler: estrategia de rechazo

También es una interfaz con un solo método. Cuando se hayan utilizado todos los recursos en el grupo de subprocesos y se rechace agregar un nuevo subproceso
, se llamará al método rechazadoExecution de RejectedExecutionHandler. El valor predeterminado es generar una
excepción de tiempo de ejecución.

Configuración del tamaño del grupo de subprocesos

Configuración del tamaño del grupo de subprocesos:

  1. Necesidad de analizar las características de las tareas realizadas por el grupo de subprocesos: uso intensivo de CPU o uso intensivo de IO
  2. ¿Cuál es el tiempo de ejecución promedio de cada tarea? El tiempo de ejecución de esta tarea también puede estar
    relacionado con si la lógica de procesamiento de la tarea implica la transmisión de red y la dependencia de los recursos del sistema subyacente.

Si requiere un uso intensivo de la CPU, principalmente para realizar tareas informáticas, el tiempo de respuesta es rápido y la CPU está funcionando todo el tiempo. Este
tipo de tarea tiene una alta tasa de utilización de la CPU, por lo que la configuración del número de subprocesos debe determinarse de acuerdo con la cantidad de núcleos de CPU, y
la cantidad de núcleos de CPU = máximo La cantidad de subprocesos de ejecución concurrentes, si la cantidad de núcleos de CPU se suma a 4, entonces el servidor puede ejecutar hasta
4 subprocesos al mismo tiempo. Demasiados subprocesos provocarán un cambio de contexto y reducirán la eficiencia. La cantidad máxima de subprocesos en el grupo de subprocesos
se puede configurar como la cantidad de núcleos de CPU + 1;

Si es intensivo en IO, realiza principalmente operaciones de IO y lleva
mucho tiempo realizar operaciones de IO. Esto se debe a que la CPU está en un estado inactivo, lo que resulta en una baja utilización de la CPU. En este caso,
el tamaño del subproceso La piscina se puede aumentar. En este caso, el tiempo de espera de los subprocesos se puede combinar para hacer un juicio: cuanto mayor sea el tiempo de espera
, más subprocesos habrá. Generalmente, puede configurar el doble de núcleos de CPU.

Una fórmula: el número óptimo de subprocesos establecido por el grupo de subprocesos = ((tiempo de espera de subprocesos establecido por el grupo de subprocesos +
tiempo de CPU del subproceso)/
tiempo de CPU del subproceso) * número de CPU
El tiempo de CPU del subproceso de esta fórmula es el subproceso único estimado del programa en la CPU Tiempo para ejecutar (generalmente use
loadrunner para probar una gran cantidad de ejecuciones y encontrar el promedio)

política de rechazo

  1. AbortPolicy: lanza una excepción directamente, la política predeterminada;
  2. CallerRunsPolicy: utiliza el hilo de la persona que llama para ejecutar la tarea;
  3. DiscardOldestPolicy: descarta la tarea principal en la cola de bloqueo y ejecuta la tarea actual;
  4. DiscardPolicy: descarta tareas directamente; por supuesto, también puede implementar
    la interfaz RejectedExecutionHandler de acuerdo con el escenario de la aplicación y personalizar la política de saturación, como registrar o almacenar persistentemente
    tareas que no se pueden procesar.

5. ¿Cuáles son los contenedores concurrentes seguros para subprocesos comunes?

CopyOnWriteArrayList, CopyOnWriteArraySet, ConcurrentHashMap
CopyOnWriteArrayList, CopyOnWriteArraySet usan copia en escritura para lograr seguridad de subprocesos
ConcurrentHashMap usa bloqueos de segmento para lograr seguridad de subprocesos


También puede consultar los siguientes artículos:
1. Explicación detallada de los 7 parámetros del grupo de subprocesos de Java

2. Grupo de subprocesos

Supongo que te gusta

Origin blog.csdn.net/qq_36256590/article/details/132382788
Recomendado
Clasificación