Resumen de programación concurrente de Java 10: marco de grupo de subprocesos

Refiérase principalmente al blog escrito anteriormente:

1: Conocimiento profundo de los grupos de subprocesos y el uso de grupos de subprocesos

2: java.util.concurrent.Executor 、 ExecutorService 、 ThreadPoolExecutor 、 Executors , ThreadFactory

 

 

Resumen del marco:

1. En orden: java.util.concurrent.Executor, ExecutorService, ThreadPoolExecutor, Executors, ThreadFactory

Según el resumen anterior:

  1. Ejecutor : La interfaz del ejecutor es también la interfaz central abstracta de nivel superior , que separa la ejecución de tareas y tareas.
  2. ExecutorService : Sobre la base de Executor, proporciona funciones como la gestión del ciclo de vida del ejecutor y la ejecución de tareas asincrónicas.
  3. ScheduledExecutorService: proporciona la función de ejecución retrasada / ejecución periódica de tareas sobre la base de ExecutorService.
  4. Ejecutores: una fábrica estática que produce actuadores específicos .
  5. ThreadFactory: Thread Factory, utilizado para crear un solo hilo, reducir el tedioso trabajo de crear hilos manualmente, y al mismo tiempo puede reutilizar las características de la fábrica.
  6. AbstractExecutorService: una implementación abstracta de ExecutorService, que proporciona una base para la implementación de varios tipos de actuadores.
  7. ThreadPoolExecutor : Thread Pool Executor, también el Executor más utilizado, puede administrar los hilos en forma de grupo de hilos.
  8. ScheduledThreadPoolExecutor: sobre la base de ThreadPoolExecutor, se agrega soporte para la programación periódica de tareas.
  9. ForkJoinPool: el grupo de subprocesos Fork / Join, introducido en JDK1.7, es la clase principal que implementa el marco Fork / Join.

2 、ThreadPoolExecutor

Submit (), invokeAll () e invokeAny () en ExecutorService son todos métodos de ejecución invocados, por lo que ejecutar es el núcleo del núcleo ;

Sus parámetros importantes: corePoolSize, maximumPoolSize, estrategia de rechazo, cola de bloqueo;

  • newFixedThreadPool : el grupo de subprocesos corePoolSize y maximumPoolSize son iguales, la cola de bloqueo usa LinkedBlockingQueue y el tamaño es el valor entero máximo;
  • newSingleThreadExecutor: Un grupo de subprocesos con un solo subproceso. La cola de bloqueo usa LinkedBlockingQueue. Si se envían tareas redundantes al grupo de subprocesos, se almacenarán temporalmente en la cola de bloqueo y se ejecutarán cuando estén libres.
  •  
  • newCachedThreadPool: grupo de subprocesos en caché, los subprocesos almacenados en caché sobreviven 60 segundos de forma predeterminada. El tamaño del grupo principal corePoolSize del subproceso es 0, el grupo principal máximo es Integer.MAX_VALUE y la cola de bloqueo usa SynchronousQueue .
  • newScheduledThreadPool : grupo de subprocesos cronometrados, este grupo de subprocesos se puede utilizar para realizar tareas periódicamente, generalmente para la sincronización periódica de datos.

Acerca de la cola de bloqueo :

  • Elija la cola de bloqueo adecuada. Tanto newFixedThreadPool como newSingleThreadExecutor utilizan colas de bloqueo ilimitadas. Las colas de bloqueo ilimitadas consumirán mucha memoria. Si se utilizan colas de bloqueo limitadas, se evitará el problema del uso excesivo de memoria, pero cuando las tareas llenen las colas de bloqueo limitadas, ¿qué debo hacer? con la nueva tarea? Cuando se utiliza una cola limitada, se debe seleccionar una estrategia de rechazo adecuada y el tamaño de la cola y el tamaño del grupo de subprocesos deben ajustarse juntos. Para grupos de subprocesos muy grandes o ilimitados, SynchronousQueue se puede usar para evitar la cola de tareas y enviar tareas directamente desde el productor al subproceso de trabajo.
  • Dado que el grupo de subprocesos del núcleo es fácil de llenar, cuando se usa SynchronousQueue, generalmente es necesario establecer el MaximumPoolSizes para que sea relativamente grande, de lo contrario, la cola fallará fácilmente y eventualmente conducirá a la ejecución de la estrategia de rechazo. El grupo de subprocesos proporcionado por los Ejecutores funciona de forma predeterminada La razón para usar SynchronousQueue como una cola de tareas.
  • SynchronousQueue no tiene capacidad y utiliza un algoritmo sin bloqueo, por lo que el rendimiento es mejor, pero cada operación de puesta en cola tiene que esperar una operación de eliminación de cola y viceversa.

Estrategia de rechazo :

  • AbortPolicy: descarta la tarea y lanza RejectedExecutionException
  • CallerRunsPolicy: Siempre que el grupo de subprocesos no esté cerrado, la política está directamente en el subproceso de la persona que llama para ejecutar las tareas actualmente descartadas. Obviamente, esto no descartará realmente la tarea, pero es muy probable que el rendimiento del hilo de envío de la tarea disminuya drásticamente.
  • DiscardOldestPolicy: descarte la solicitud más antigua de la cola, que es una tarea que está a punto de ejecutarse, e intente enviar la tarea actual nuevamente.
  • DiscardPolicy: descarta la tarea sin ningún procesamiento.

3 、ExecutorService

El método principal de ExecutorService es el método de envío , que se usa para enviar una tarea para que se ejecute. Si los lectores leen el código fuente de ThreadPoolExecutor, encontrarán que no anula el método de envío, sino que usa la plantilla de la clase principal AbstractExecutorService, y luego implementa el método ejecutar por sí mismo .

4. Explicación detallada y comparación de los principios de implementación de ArrayBlockingQueue y LinkedBlockingQueue:

ArrayBlockingQueue utiliza internamente matrices para el almacenamiento de datos ( 属性items), para garantizar la seguridad de los subprocesos , se utiliza ReentrantLock lockpara garantizar la inserción y eliminación bloqueables de datos utilizando Condición , cuando el subproceso del consumidor que obtiene datos está bloqueado, el subproceso se colocará en el Cola de espera notEmpty, cuando el hilo del productor que inserta datos está bloqueado, el hilo se colocará en la cola de espera notFull.

LinkedBlockingQueue es una cola de bloqueo limitada implementada con una lista enlazada.Cuando se especifica el tamaño de la cola cuando se construye el objeto, el tamaño predeterminado de la cola es Integer.MAX_VALUE.

Se puede ver que la principal diferencia con ArrayBlockingQueue es : LinkedBlockingQueue usa dos bloqueos diferentes ( takeLocky putLock) para controlar la seguridad de los subprocesos al insertar y eliminar datos . Por lo tanto, estos dos bloqueos también generan dos condiciones correspondientes. ( notEmptyY notFull) para lograr bloqueos inserción y borrado de datos.

Comparación de los dos:

El mismo punto : ArrayBlockingQueue y LinkedBlockingQueue es a través del mecanismo de notificación de condición para lograr bloquear elementos de inserción y eliminación, y cumplir con las características de seguridad para subprocesos;

Diferencia :

  1.  La capa inferior de ArrayBlockingQueue se implementa mediante una matriz, mientras que LinkedBlockingQueue utiliza una estructura de datos de lista enlazada;
  2. ArrayBlockingQueue inserta y elimina datos, usando solo un bloqueo, y LinkedBlockingQueue está en la inserción y eliminación que se usaron putLocky, takeLockpor lo tanto, puede reducir la posibilidad de subprocesos porque el subproceso no puede entrar en el bloqueo y entrar en el estado de ESPERA, lo que aumenta la efectividad de los subprocesos de ejecución simultánea.

 

Supongo que te gusta

Origin blog.csdn.net/ScorpC/article/details/113914729
Recomendado
Clasificación