Ejecutor.newCachedThreadPool () versus Ejecutores.Nuevo conjunto de herramientas()


newCachedThreadPool() versus newFixedThreadPool()

¿Cuándo debo usar uno u otro? ¿Qué estrategia es mejor en términos de utilización de recursos?

Author: dimo414, 2009-06-04

7 answers

Creo que los documentos explican la diferencia y el uso de estas dos funciones bastante bien:

newFixedThreadPool

Crea un grupo de subprocesos que reutiliza un número fijo de hilos que funcionan apagado una cola compartida sin límites. En cualquier punto, en la mayoría de los hilos nThreads estar activo procesando tareas. Si las tareas adicionales se envían cuando todos los hilos están activos, esperarán en la cola hasta que un hilo es disponible. Si cualquier hilo termina debido a un fallo durante la ejecución antes del apagado, una nueva tomará su lugar si es necesario para ejecutar tareas posteriores. Los hilos en el pool existirá hasta que sea explícitamente apagado.

newCachedThreadPool

Crea un grupo de subprocesos que crea nuevos hilos según sea necesario, pero se reutilizará hilos construidos previamente cuando están disponibles. Estas piscinas serán normalmente mejorar el rendimiento de programas que ejecutan muchos programas de corta duración tareas asíncronas. Llamadas a ejecutar reutilizará construido previamente hilos si están disponibles. Si no existe el hilo está disponible, un nuevo hilo ser creado y añadido a la piscina. Hilos que no se han utilizado para sesenta segundos se terminan y eliminado de la caché. Por lo tanto, una piscina que permanece inactivo durante el tiempo suficiente no consumir ningún recurso. Tenga en cuenta que piscinas con propiedades similares pero diferentes detalles (por ejemplo, parámetros de tiempo de espera) se pueden crear usando ThreadPoolExecutor constructor.

En términos de recursos, el newFixedThreadPool mantendrá todos los subprocesos en ejecución hasta que se terminen explícitamente. En el newCachedThreadPool los hilos que no se han utilizado durante sesenta segundos se terminan y se eliminan de la caché.

Dado esto, el consumo de recursos, dependerá mucho de la situación. Por ejemplo, si tiene un gran número de tareas de larga duración, sugeriría el FixedThreadPool. En cuanto a CachedThreadPool, los documentos dicen que " Estos pools normalmente mejorarán la ejecución de programas que ejecutan muchas tareas asíncronas de corta duración".

 158
Author: bruno conde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-21 13:55:59

Solo para completar las otras respuestas, me gustaría citar Effective Java, 2a Edición, por Joshua Bloch, capítulo 10, Ítem 68:

"Elegir el servicio ejecutor para una aplicación en particular puede ser complicado. Si estás escribiendo un pequeño programa, o servidor ligeramente cargado, con Ejecutores.new-CachedThreadPool es generalmente una buena opción, ya que no requiere configuración y generalmente "hace lo correcto."Pero un grupo de subprocesos en caché es no es una buena opción para un servidor de producción muy cargado!

En un grupo de subprocesos en caché, las tareas enviadas no se ponen en cola sino que se entregan inmediatamente a un subproceso para su ejecución. Si no hay hilos disponibles, se crea uno nuevo. Si un servidor está tan cargado que todas sus CPU se utilizan completamente, y llegan más tareas, se crearán más subprocesos, lo que solo empeorará las cosas.

Por lo tanto, en un servidor de producción , es mucho mejor usar Ejecutores .newFixedThreadPool , que le da un grupo con un número fijo de hilos, o usando la clase ThreadPoolExecutor directamente, para un control máximo."

 53
Author: Louis F.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-15 09:21:44

Si ves el código en el grepcode, verás que están llamando a ThreadPoolExecutor. internamente y estableciendo sus propiedades. Usted puede crear su uno para tener un mejor control de su requisito.

public static ExecutorService newFixedThreadPool(int nThreads) {
   return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
 10
Author: krmanish007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-17 18:28:34

Así es, Executors.newCachedThreadPool() no es una gran opción para el código de servidor que da servicio a múltiples clientes y solicitudes simultáneas.

¿Por qué? Hay básicamente dos problemas (relacionados) con él:

  1. No tiene límites, lo que significa que está abriendo la puerta para que cualquiera lisie su JVM simplemente inyectando más trabajo en el servicio (ataque DoS). Los hilos consumen una cantidad no despreciable de memoria y también aumentan el consumo de memoria en función de su trabajo en curso, por lo que es bastante fácil de derribar un servidor de esta manera (a menos que tenga otros disyuntores en su lugar).

  2. El problema ilimitado se ve exacerbado por el hecho de que el Ejecutor está encabezado por un SynchronousQueue, lo que significa que hay una transferencia directa entre el dador de tareas y el grupo de subprocesos. Cada nueva tarea creará un nuevo hilo si todos los hilos existentes están ocupados. Esta es generalmente una mala estrategia para el código del servidor. Cuando la CPU se satura, las tareas existentes tardan más en terminar. Sin embargo, se están realizando más tareas enviado y más hilos creados, por lo que las tareas tardan más y más en completarse. Cuando la CPU está saturada, más hilos definitivamente no es lo que el servidor necesita.

Aquí están mis recomendaciones:

Utilice un grupo de subprocesos de tamaño fijo Ejecutores.newFixedThreadPool o un ThreadPoolExecutor. con un número máximo establecido de hilos;

 7
Author: Prashant Gautam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-05 11:43:25

Si no te preocupa la cola ilimitada de tareas Llamables/Ejecutables, puedes usar una de ellas. Como sugiere Bruno, yo también prefiero newFixedThreadPool a newCachedThreadPool entre estos dos.

Pero ThreadPoolExecutor proporciona características más flexibles en comparación con newFixedThreadPool o newCachedThreadPool

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

Ventajas:

  1. Tienes control total sobre el tamaño de BlockingQueue . No está sin límite a diferencia de las dos opciones anteriores. No voy a salir de error de memoria debido a la enorme acumulación de tareas pendientes ejecutables/ejecutables en turbulencias inesperadas en el sistema.

  2. Puede implementar una política personalizada de manejo de rechazo O usar una de las políticas:

    1. En el valor predeterminado ThreadPoolExecutor.AbortPolicy, el controlador lanza una excepción en tiempo de ejecución RejectedExecutionException tras el rechazo.

    2. En ThreadPoolExecutor.CallerRunsPolicy, el subproceso que invoca a execute ejecuta la tarea. Esto proporciona un mecanismo de control de retroalimentación simple que ralentizará la califique que se envían nuevas tareas.

    3. En ThreadPoolExecutor.DiscardPolicy, una tarea que no se puede ejecutar simplemente se elimina.

    4. En ThreadPoolExecutor.DiscardOldestPolicy, si el ejecutor no se apaga, la tarea a la cabeza de la cola de trabajo se cae, y luego se vuelve a intentar la ejecución (lo que puede fallar de nuevo, causando que esto se repita.)

  3. Puede implementar la fábrica de hilos personalizados para los siguientes casos de uso:

    1. Para establecer un nombre de hilo más descriptivo
    2. Para establecer estado del demonio de hilo
    3. Para establecer la prioridad del hilo
 7
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-06 06:13:34

Debe usar newCachedThreadPool solo cuando tenga tareas asíncronas de corta duración como se indica en Javadoc, si envía tareas que tardan más tiempo en procesarse, terminará creando demasiados subprocesos. Puede alcanzar el 100% de CPU si envía tareas de ejecución larga a un ritmo más rápido a newCachedThreadPool (http://rashcoder.com/be-careful-while-using-executors-newcachedthreadpool/).

 3
Author: Dhanaraj Durairaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-15 12:04:07

Hago algunas pruebas rápidas y tengo los siguientes hallazgos:

1) si se usa SynchronousQueue:

Después de que los hilos alcancen el tamaño máximo, cualquier trabajo nuevo será rechazado con la excepción como abajo.

Excepción en el hilo "main" java.útil.concurrente.RejectedExecutionException: Task java.útil.concurrente.FutureTask@3fee733d rechazado desde java.útil.concurrente.ThreadPoolExecutor@5acf9800 [Ejecución , tamaño del grupo = 3, hilos activos = 3, tareas en cola = 0, tareas completadas = 0]

En java.útil.concurrente.ThreadPoolExecutor Ab AbortPolicy.Ejecución rechazada (ThreadPoolExecutor.java:2047)

2) si se usa LinkedBlockingQueue:

Los hilos nunca aumentan de tamaño mínimo a tamaño máximo, lo que significa que el grupo de hilos es de tamaño fijo como el tamaño mínimo.

 0
Author: Mike Lin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-12 21:18:58