[Herramienta de concurrencia Java clase-división del trabajo] cómo crear correctamente un grupo de subprocesos

1. Consumo del grupo de subprocesos

Java crea un objeto y asigna un espacio de memoria en la memoria del montón. Para crear un subproceso, debe llamar a la API del núcleo del sistema operativo, y luego el sistema operativo debe asignar una serie de recursos para el subproceso, ¡lo cual es muy costoso!

** El hilo es un objeto pesado, y debes evitar la creación y destrucción frecuentes. ** Entonces el esquema del grupo de subprocesos es bueno.

2. El grupo de subprocesos es en realidad un modelo de consumidor productor

Grupo de subprocesos, lo primero que piensa es agrupar recursos, es decir, cuando necesita usar recursos, solicitar recursos y usarlos para liberar recursos, pero el grupo de subprocesos no es así, ni puede serlo.

El grupo de subprocesos es en realidad un modelo productor-consumidor, el consumidor del subproceso es el productor (tarea de la tarea de producción) y el grupo de subprocesos en sí mismo es el consumidor (tarea de la tarea de consumo).

2.1 Implementar manualmente el grupo de subprocesos

Principio: se agrega una cola de bloqueo al grupo de subprocesos, que almacena la tarea Ejecutable que se ejecutará. El número especificado de subprocesos de subprocesos se crea en el método de construcción del grupo de subprocesos y se coloca en la lista del grupo de subprocesos, y se inicia el inicio. La función interna de ejecución () mientras el bucle continúa Elimine la tarea de la cola de bloqueo y ejecútela.

//简化的线程池,仅用来说明工作原理
class MyThreadPool{
  //阻塞队列存放Runable任务
  BlockingQueue<Runnable> workQueue;
  //线程池列表,用来保存线程
  List<WorkerThread> threads = new ArrayList<>();
  // 构造方法
  MyThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
    this.workQueue = workQueue;
    // 创建工作线程
    for(int idx=0; idx<poolSize; idx++){
      WorkerThread work = new WorkerThread();
      work.start();//启动线程池中的所有线程
      threads.add(work);//把线程添加到线程池列表中
    }
  }
  // 提交任务
  void execute(Runnable command){
    workQueue.put(command);
  }
  // 工作线程负责消费任务,并执行任务
  class WorkerThread extends Thread{
    public void run() {
      //循环取任务并执行
      while(true){ ①
        Runnable task = workQueue.take();
        task.run();
      } 
    }
  }  
}
/** 下面是使用示例 **/
// 创建有界阻塞队列
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(2);
// 创建线程池  
MyThreadPool pool = new MyThreadPool(10, workQueue);
// 提交任务  
pool.execute(()->{System.out.println("hello");});

3. ¿Cómo usar el grupo de hilos de Java?

El grupo de subprocesos proporcionado en el paquete concurrente de Java es mucho mejor que el grupo de subprocesos que implementamos anteriormente, el núcleo es ThreadPoolExecutor .

3.1 Método de construcción ThreadPoolExecutor

El siguiente es el constructor de ThreadPoolExecutor.

ThreadPoolExecutor(
  int corePoolSize,
  int maximumPoolSize,
  long keepAliveTime,
  TimeUnit unit,
  BlockingQueue<Runnable> workQueue,
  ThreadFactory threadFactory,
  RejectedExecutionHandler handler) 

Vamos a presentar los parámetros del grupo de subprocesos uno por uno:

  • corePoolSize : el número mínimo de subprocesos que se mantienen en el grupo de subprocesos. Incluso si el programa no tiene una tarea que ejecutar, debería haber varios subprocesos en espera de ejecutarse. Si el subproceso actual sobrevive más, el número de subprocesos activos se reduce en consecuencia.

    • Método allowCoreThreadTimeOut (valor booleano): cuando el proyecto está muy ocupado, puede retirar todos los hilos, sin dejar un hilo mínimo maximumPoolSize.
  • maximumPoolSize : representa el número máximo de subprocesos que puede crear el grupo de subprocesos. Si actualmente hay menos subprocesos supervivientes, aumente el número de subprocesos en consecuencia.

  • keepAliveTime & unit : los dos parámetros anteriores aumentan y disminuyen el subproceso en consecuencia de acuerdo con la ejecución del subproceso durante un período de tiempo. keepAliveTime & unit debe definir este tiempo. Si un subproceso ha estado inactivo, keepAliveTime & unit durante tanto tiempo y el número de subprocesos El hilo inactivo se recuperará.

  • workQueue : cola de trabajo, que es sinónimo de la cola que implementa manualmente el grupo de subprocesos anterior y almacena las tareas que se ejecutarán.

  • threadFactory : puede crear hilos de acuerdo con esta costumbre, por ejemplo, asignar un nombre significativo al hilo.

  • manejador : puede usar esta estrategia personalizada de rechazo de tareas. Cuando todos los hilos en el grupo de hilos se están ejecutando y las tareas en la cola de trabajo están llenas, el grupo de hilos puede negarse a aceptar la tarea y rechazarla cuando se envía la tarea. La estrategia se puede especificar con el controlador.
    Cuatro estrategias proporcionadas por ThreadPoolExecutor:

    • CallerRunsPolicy: el subproceso que envió la tarea realiza la tarea en sí.
    • AbortPolicy: la política de rechazo predeterminada arrojará RejectedExecutionException.
    • DiscardPolicy: descarta la tarea directamente sin ninguna excepción.
    • DiscardOldestPolicy: descartar la tarea más antigua es descartar la tarea más antigua que ingresó a la cola de trabajo y luego agregar la nueva tarea a la cola de trabajo.

3.2 Notas sobre el uso del grupo de subprocesos

  1. Intente usar ThreadPoolExecutor en desarrollo, no use Executors para crear rápidamente un grupo de subprocesos.
  2. Se recomienda utilizar colas limitadas.
  3. La estrategia de rechazo predeterminada, lanzar excepciones, usar con precaución,
  4. Manejo de excepciones: como el método de ejecución del objeto ThreadPoolExecutor, envíe la tarea, si se produce una excepción durante la ejecución de la tarea, hará que el subproceso finalice y la tarea será anormal, pero no recibirá ninguna notificación de excepción, lo que le permitirá pensar erróneamente que todas las tareas se ejecutan normalmente. Entonces, la forma más segura es atrapar excepciones.
try {
  //业务逻辑
} catch (RuntimeException x) {
  //按需处理
} catch (Throwable x) {
  //按需处理
} 

Más: Deng Xin
Referencia: Geek Time

Publicado 34 artículos originales · Me gusta0 · Visitas 1089

Supongo que te gusta

Origin blog.csdn.net/qq_42634696/article/details/105448220
Recomendado
Clasificación