Una demostración le permite comprender a fondo el flujo de trabajo del grupo de subprocesos

inserte la descripción de la imagen aquí

Hay demasiados artículos sobre grupos de subprocesos en Internet. No diré mucho. Si lo dices, no puedes recordarlo, no puedes entenderlo si lo recuerdas y no puedes usarlo si tú lo entiendes...

Después de pensarlo durante mucho tiempo, finalmente se me ocurrió una demostración, más diez escenarios, para que pueda comprender gradualmente el flujo de trabajo real del grupo de subprocesos.

Créame, después de leer este artículo detenidamente, puede dominar a fondo un punto básico de conocimiento de Java, sin pérdida


El grupo de subprocesos no es más que unos pocos parámetros: subproceso principal, subproceso máximo, tiempo de recuperación, cola, nada difícil, puede aprenderlo si lo tiene.

Iré a la demostración directamente aquí. Si no sabe el significado de los parámetros, puede ir a la puerta de al lado para recuperar la lección. Aunque este artículo también lo mencionará, será mejor que sepa algo primero. El resumen del mecanismo de ejecución de la implementación del grupo de subprocesos

sobre el talento

public class ThreadPoolExecutorTest {
    
    
    private static int taskCount = 50;//任务数
    private static AtomicInteger taskCountExecuted;//实际完成任务数

    public static void main(String[] args) {
    
    
        taskCountExecuted = new AtomicInteger();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                10,//核心线程数
                20,//最大线程数
                5,//非核心回收超时时间
                TimeUnit.SECONDS,//超时时间单位
                new ArrayBlockingQueue<>(30)//任务队列
        );
        System.out.println("总任务数:" + taskCount);
        long start = System.currentTimeMillis();
        //模拟任务提交
        for (int i = 0; i < taskCount; i++) {
    
    
            Thread thread = new Thread(() -> {
    
    
                try {
    
    
                    Thread.sleep(500);//模拟执行耗时
                    System.out.println("已执行" + taskCountExecuted.addAndGet(1) + "个任务");
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            });
            try {
    
    
                //注意这里我try起来了,默认拒绝策略会报错
                executor.execute(thread);
            } catch (RejectedExecutionException e) {
    
    
                taskCount = executor.getActiveCount() + executor.getQueue().size();
            }
        }
        long end = 0;
        while (executor.getCompletedTaskCount() < taskCount) {
    
    
            end = System.currentTimeMillis();
        }
        System.out.println(taskCountExecuted + "个任务已执行,总耗时:" + (end - start));
        executor.shutdown();
    }
}

El punto está aquí, echemos un vistazo a la demostración con preguntas.

Como se indicó anteriormente, se ha creado un nuevo grupo de subprocesos, la cantidad de subprocesos principales es 10, la cantidad máxima de subprocesos es 20 y la capacidad de la cola de tareas es 30. ¡Escuche la pregunta! !

Pregunta 0: envíe 5 tareas al grupo de subprocesos anterior. ¿Cuánto tiempo lleva completar la ejecución de la tarea?

Análisis: tengo 10 subprocesos principales, lo que significa que 10 subprocesos estarán activos durante mucho tiempo y las tareas entrantes se pueden ejecutar de inmediato. 5<10, por lo que las 5 tareas se ejecutan de inmediato. El paralelismo de subprocesos múltiples es, por supuesto, asíncrono , por lo que se necesitan 500 ms para
inserte la descripción de la imagen aquí
insertar uno Boca: ¿Por qué no 500 sino 540, porque lleva tiempo ejecutar el código, después de todo, es una tarea de envío simulada, no enviada realmente en un instante, y el error está relacionado con el frecuencia de la cpu de tu computadora

Pregunta 1: ¿Cuánto tiempo se tarda en enviar 10 tareas?

Todavía son 500, 10 tareas y 5 tareas son en realidad las mismas, no exceden la cantidad de subprocesos principales y se ejecutan una por una.
inserte la descripción de la imagen aquí

Pregunta 2: ¿Cuánto tiempo se tarda en enviar 11 tareas?

1000, no se sorprenda, este es el punto clave que muchas personas no entienden el mecanismo del grupo de subprocesos. Aunque solo hay una tarea más, la tarea 11 no se ejecutará de inmediato, porque la cola no está llena, por lo que las primeras 10 tareas se ejecutarán de inmediato, y la undécima se colocará en la cola y se ejecutará después de que se desocupe un subproceso.
inserte la descripción de la imagen aquí

Pregunta 3: ¿Cuánto tiempo se tarda en enviar 20 tareas?

También son 1000, no preguntes por qué, no seas grosero, hoy viene Jesús, también son 1000, estas 20 tareas, las primeras 10 tareas se ejecutarán una por una, del 11 al 20 serán todas arrojados a la cola, los diez actuales La tarea se sacará de la cola y se ejecutará después de que se haya ejecutado la tarea.
inserte la descripción de la imagen aquí

Pregunta 4: ¿Cuánto tiempo se tarda en enviar 30 tareas?

Por supuesto que es 1500, 30/10=3, 3*500=1500
inserte la descripción de la imagen aquí

Pregunta 5: ¿Cuánto tiempo se tarda en enviar 40 tareas?

Por supuesto que es 2000, 10+10+10+10, no quiero explicar
inserte la descripción de la imagen aquí

¡Aquí viene el punto! !
¡Aquí viene el punto! !
¡Aquí viene el punto! !

Pregunta 6: ¿Cuánto tiempo se tarda en enviar 41 tareas?

También es 2000. Mucha gente pensará que es 1500, 11+11+11+8. En realidad no lo es. Lo escribiré aquí. Lo diré más adelante.
inserte la descripción de la imagen aquí

Pregunta 7: ¿Cuánto tiempo se tarda en enviar 45 tareas?

1500, sí 1500, 15+15+15
inserte la descripción de la imagen aquí

Pregunta 8: ¿Cuánto tiempo se tarda en enviar 50 tareas?

1500, 20+20+10
inserte la descripción de la imagen aquí
Pregunta 9: ¿Cuánto tiempo se tarda en enviar 51 tareas?
También es 1500. Este grupo de subprocesos puede recibir un máximo de 50 tareas al mismo tiempo, porque no he establecido una política de rechazo. El valor predeterminado es AbortPolicy, es decir, las tareas excedidas se descartarán y se lanzará una excepción RejectedExecutionException. No hay ningún error en la demo porque lo intenté

Finalmente, hablemos del problema sobrante ahora mismo, ¿por qué 41 tareas son 2000 y 45 tareas son 1500?

De hecho, mucha gente no entiende esto. Escribí una serie de signos más para las siguientes preguntas (si entiendes esto, puedes dominar el grupo de subprocesos)

Por ejemplo, cuando hay tareas 40, 10 + 10 + 10 + 10, lo que significa que todas las tareas se completan en grupos 4, y cada grupo ejecuta tareas 10. Debido a que los subprocesos múltiples son asincrónicos, el tiempo de ejecución de cada grupo es igual al tiempo de ejecución de una sola tarea , es decir, 500 ms, por lo que 40 tareas son 500+500+500+500=2000

Y cuando hay 41 tareas, son 11+11+11+8, por lo que 40 tareas también son 500+500+500+500=2000 (definitivamente habrá un pequeño socio preguntando, 41 tareas han excedido la capacidad de la cola y los subprocesos en el grupo de subprocesos son Por qué no se alcanzó el número máximo de subprocesos, debería ser 20+20+1)

Recuerde que
cuando la cantidad de tareas <= la cantidad de subprocesos principales, la cantidad de subprocesos de trabajo en el grupo de subprocesos = la cantidad de tareas
Subprocesos principales + capacidad de cola < cantidad de tareas <= cantidad máxima de subprocesos + capacidad de cola, la cantidad de subprocesos de trabajo = número de tareas - capacidad de la cola

entonces

seguir viendo

Cuando hay 41 tareas, 41-30=11, y el lote de ejecución es 11+11+11+8, es decir 500+500+500+500=2000 ¿Hay algún problema? No hay problema

Cuando hay 45 tareas, 45-30=15, entonces 15+15+15, es decir, 500+500+500=1500, ¿hay algún problema? No hay problema

Cuando hay 50 tareas, 50-30=20, 20+20+10, es decir 500+500+500=1500, ¿hay algún problema? todavía no hay problema


Una pregunta después de la clase, ¿cuánto tiempo toma 44 tareas?

Espero que salgas a correr solo, no seas ignorante.


Agregue algo de conocimiento frío al final del artículo. La cantidad de subprocesos principales también se puede reciclar. ThreadPoolExecutor tiene un atributo llamado allowCoreThreadTimeOut
inserte la descripción de la imagen aquí
. ThreadPoolExecutor nos proporciona un método público allowCoreThreadTimeOut, que se puede establecer mediante **allowCoreThreadTimeOut( true )**
inserte la descripción de la imagen aquí


Blog se escribe hoy

Ayer pensé en la demostración.

Se me cayó el pelo cuando quise hacer una demostración anteayer

Esta es la demostración que obtuve por unos pelos. El jefe estará emocionado de abofetear la silla de ruedas cuando la vea. Si la familia tiene las condiciones, copian la demostración y corren a correr, y recitan y recitan el texto completo sin condiciones

fin
_


Ok. Ya terminé

Supongo que te gusta

Origin blog.csdn.net/qq_33709582/article/details/121653584
Recomendado
Clasificación