JAVA implementa cuatro formas de subprocesos múltiples y el contenido del grupo de subprocesos ThreadPoolExecutor explicación detallada de la estrategia de rechazo de siete parámetros grupo de subprocesos personalizado

Análisis detallado del grupo de subprocesos en cuatro formas de subprocesos múltiples JAVA

Java multihilo de cuatro formas

4 formas de implementar subprocesos en java:

  • 1. Herede la clase Thread y anule el método de ejecución
  • 2. Implementar la interfaz Runnable e implementar el método de ejecución
  • 3. Herede la interfaz Callable para implementar el método de llamada y use futureTask para llamar (con valor de retorno / puede manejar excepciones)

[Los tres tipos anteriores no se utilizan en códigos comerciales normales].

[Todas las tareas asincrónicas de subprocesos múltiples deben entregarse al grupo de subprocesos para su ejecución]

  • 4. Grupo de subprocesos (reutilización de subprocesos; controlar el número máximo de subprocesos simultáneos; administrar subprocesos)

    • Reducir el consumo de recursos

      • Reduzca la pérdida causada por la creación y destrucción de subprocesos mediante la reutilización de subprocesos ya creados
    • Mejorar la velocidad de respuesta

      • Debido a que el número de subprocesos en el grupo de subprocesos no excede el límite máximo, algunos subprocesos están en un estado de espera para que se asignen tareas y, cuando llegan las tareas, se pueden ejecutar sin crear nuevos subprocesos.
    • Mejorar la capacidad de administración de subprocesos

      • El grupo de subprocesos optimizará los subprocesos en el grupo de acuerdo con las características del sistema actual para reducir la sobrecarga del sistema causada por la creación y destrucción de subprocesos. La creación y destrucción inalámbrica de subprocesos no solo reduce los recursos del sistema, sino que también reduce la estabilidad del sistema, y ​​usa el grupo de subprocesos para uniformidad distribución

1. Herede la clase Thread y anule el método de ejecución

public class ThreadTest {
    
    
    public  static void main(String args[]){
    
    
        System.out.println("main start ....");
//        1.继承Thread类 重写run方法
        new Thread01().start();
        System.out.println("main end ....");
    }
    public static class Thread01 extends  Thread{
    
    
        @Override
        public void run() {
    
    
            System.out.println("1.继承Thread类 重写run方法");
        }
    }
}

2. Implementar la interfaz Runnable e implementar el método de ejecución

public class ThreadTest {
    
    
    public  static void main(String args[]){
    
    
        System.out.println("main start ....");
//         2.实现Runnable接口 实现run方法
        new Thread(new Runnable01()).start();
        System.out.println("main end ....");
    }
    public static class Runnable01 implements  Runnable{
    
    
        @Override
        public void run() {
    
    
            System.out.println("2.实现Runnable接口 实现run方法");
        }
    }
}

3. Herede la interfaz Callable para implementar el método de llamada y use futureTask para llamar (con valor de retorno / puede manejar excepciones)

public class ThreadTest {
    
    
    public  static void main(String args[]) throws ExecutionException, InterruptedException {
    
    
        System.out.println("main start ....");
//        3.继承Callable接口 实现call方法 使用futureTask调用  (有返回值/可处理异常)
        Callable01 callable01 = new Callable01();
        FutureTask<Integer> futureTask = new FutureTask<>(callable01);
        new Thread(futureTask).start();
        //使用futureTask 获取返回值  会阻塞等待
        System.out.println(futureTask.get());
        System.out.println("main end ....");
    }
    public static class Callable01 implements Callable<Integer>{
    
    

        @Override
        public Integer call() throws Exception {
    
    
            System.out.println("3.继承Callable接口 实现call方法 使用futureTask调用  (有返回值/可处理异常)");
            return new Integer(200);
        }
    }
}

4. Grupo de subprocesos

4.1 Aplicación del grupo de subprocesos básico

public class ThreadTest {
    
    
    //正常情况保证一个项目中只有少数线程池,每个异步任务,线程池让他自己取执行
    //Executors.newFixedThreadPool(10); 使用工具类生成容量为10的线程池
    //自定义线程池使用  new ThreadPoolExecutor();  自定义七大参数
    public static ExecutorService service = Executors.newFixedThreadPool(10);
    public  static void main(String args[]){
    
    
        System.out.println("main start ....");
        try{
    
    
            service.execute(()->{
    
    
                System.out.println("4.线程池");
            });
        }catch (Exception e){
    
    
                e.printStackTrace();
        }finally{
    
    
            service.shutdown();
        }
        System.out.println("main end ....");
    }

}

4.2 Herramientas auxiliares de los ejecutores

Executors.newFixedThreadPool(int);  //创建固定容量的线程池
Executors.newSingleThreadExecutor();  //创建一个只有1个工作线程的线程池
Executors.newCachedThreadPool() //创建一个可扩容的线程池。执行很多短期异步任务,线程池根据需要创建新线程,但在先前构造的线程可用时将重用他们。可扩容。
public class MyThreadPoolDemo {
    
    
    public  static void main(String args[]){
    
    
        //固定容量的线程池
//        ExecutorService threadPool =Executors.newFixedThreadPool(5); //创建一个有5个工作线程的线程池
//        ExecutorService threadPool =Executors.newSingleThreadExecutor(); //创建一个只有1个工作线程的线程池
        ExecutorService threadPool =Executors.newCachedThreadPool();  //创建一个可扩容的线程池
        try{
    
    
            for (int i = 1; i <10; i++) {
    
    
                //从线程池中使用一个工作线程
                threadPool.execute(()->{
    
    
                    System.out.println(Thread.currentThread().getName());
                });
            }
        }catch (Exception e){
    
    

        }finally{
    
    
            //任务结束 归还线程
            threadPool.shutdown();
        }
    }
}

Las capas inferiores de las tres API de Ejecutores anteriores se implementan utilizando ThreadPoolExecutor con diferentes parámetros.
Inserte la descripción de la imagen aquí

4.3 Análisis de los siete parámetros de ThreadPoolExecutor

Inserte la descripción de la imagen aquí

  • 1.corePoolSize: la cantidad de subprocesos centrales residentes en el subproceso

  • 2, maxmunPoolSize: el número máximo de subprocesos que se pueden ejecutar simultáneamente en el grupo de subprocesos, este valor debe ser mayor que 1

  • 3. KeepAliveTime: el tiempo de supervivencia de los subprocesos inactivos redundantes. Cuando el número de subprocesos en el grupo actual excede corePoolSize && cuando el tiempo de inactividad alcanza keepAliveTime, los subprocesos adicionales se destruirán hasta que queden subprocesos corePoolSize (estrategia de exceso)

  • 4. unidad: unidad keepAliveTime

  • 5. workQueue: cola de bloqueo de tareas, tareas que se han enviado pero aún no se han ejecutado (estrategia insuficiente)

  • 6, threadFactory: representa la fábrica de subprocesos que genera subprocesos de trabajo en el grupo de subprocesos y se utiliza para crear subprocesos. Generalmente el valor predeterminado está bien

  • 7. Manejador: estrategia de rechazo, lo que significa que cuando la cola de bloqueo de tareas está llena y el número total de subprocesos de trabajo es mayor o igual al número máximo de subprocesos en el grupo de subprocesos (maxmunPoolSize), cómo rechazar la estrategia ejecutable (estrategia completa) solicitada para la ejecución

4.4 Principio de funcionamiento de ThreadPoolExecutor

  • 1. Después de crear el grupo de subprocesos, comience a esperar solicitudes.

  • 2. Al llamar al método execute () para agregar una tarea de solicitud, el grupo de subprocesos hará los siguientes juicios:

    2.1 Si el número de subprocesos en ejecución es menor que corePoolSize, cree inmediatamente un subproceso para ejecutar esta tarea;

    2.2 Si el número de subprocesos en ejecución es mayor o igual que corePoolSize, coloque la tarea en la cola;

    2.3 Si la cola está llena en este momento y el número de subprocesos en ejecución sigue siendo menor que el tamaño máximo de la piscina, entonces aún debe crear un subproceso no central para ejecutar esta tarea inmediatamente;

    2.4 Si la cola está llena y el número de subprocesos en ejecución es mayor o igual que maximumPoolSize, entonces el grupo de subprocesos iniciará la estrategia de rechazo de saturación para ejecutarse.

  • 3. Cuando un subproceso completa su tarea, eliminará la siguiente tarea de la cola para su ejecución.

  • 4. Cuando un hilo no tiene nada que hacer durante más de un cierto período de tiempo (keepAliveTime), el hilo juzgará:
    si el número de hilos actualmente en ejecución es mayor que corePoolSize, entonces este hilo se detendrá.
    Entonces, después de que se completen todas las tareas del grupo de subprocesos, eventualmente se reducirá al tamaño de corePoolSize.

4.5 Grupo de subprocesos personalizados

Use 7 parámetros para personalizar el grupo de subprocesos (el parámetro más importante es la estrategia de rechazo)

public class MyThreadPoolDemo {
    
    
    public  static void main(String args[]){
    
    
       ExecutorService threadPool = new ThreadPoolExecutor(2,
                5,
                2L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<Runnable>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
}

Cuatro estrategias principales de rechazo:

1. ThreadPoolExecutor.AbortPolicy (); lanza RejectExecutionException directamente para evitar que el sistema funcione con normalidad

2. ThreadPoolExecutor.CallerRunsPolicy (); La persona que llama ejecuta un mecanismo de ajuste. Esta estrategia no abandona tareas ni arroja excepciones, pero devuelve ciertas tareas a la persona que llama, lo que reduce el flujo de nuevas tareas.

3. ThreadPoolExecutor.DiscardOldestPolicy (); Descarte la tarea de espera más larga en la cola, luego agregue la tarea actual a la cola e intente enviar la tarea actual nuevamente

4. ThreadPoolExecutor.DiscardPolicy (); Esta estrategia descarta silenciosamente las tareas que no se pueden procesar, no maneja ninguna tarea o arroja excepciones. Si se permite que la tarea se pierda, esta es la mejor estrategia.

Mecanismo, esta estrategia no abandona tareas ni arroja excepciones, sino que devuelve determinadas tareas a la persona que llama, lo que reduce el flujo de nuevas tareas.

3. ThreadPoolExecutor.DiscardOldestPolicy (); Descarte la tarea de espera más larga en la cola, luego agregue la tarea actual a la cola e intente enviar la tarea actual nuevamente

4. ThreadPoolExecutor.DiscardPolicy (); Esta estrategia descarta silenciosamente las tareas que no se pueden procesar, no maneja ninguna tarea o arroja excepciones. Si se permite que la tarea se pierda, esta es la mejor estrategia.

Supongo que te gusta

Origin blog.csdn.net/weixin_44634197/article/details/108345736
Recomendado
Clasificación