Tengo un programa que genera subprocesos (~ 5-150) que realizan un montón de tareas. Originalmente, usé un FixedThreadPool
porque esta pregunta similar sugería que eran más adecuados para tareas de mayor duración y, con mi conocimiento muy limitado de subprocesos múltiples, consideré que la vida media de los subprocesos (varios minutos) era "de larga duración ".
Sin embargo, recientemente agregué la capacidad de generar subprocesos adicionales y hacerlo me lleva por encima del límite de subprocesos que establecí. En este caso, ¿sería mejor adivinar y aumentar el número de subprocesos que puedo permitir o cambiar a uno CachedThreadPool
para no tener subprocesos desperdiciados?
Probándolos a ambos de manera preliminar, no parece haber una diferencia, así que me inclino a ir con los CachedThreadPool
justos para evitar el desperdicio. Sin embargo, ¿la vida útil de los subprocesos significa que debería elegir un FixedThreadPool
subproceso y simplemente ocuparme de los subprocesos no utilizados? Esta pregunta hace que parezca que esos hilos adicionales no se desperdician, pero agradecería la aclaración.
ThreadPoolExecutor
gusta acotadoThreadPoolExecutor(0, maximumPoolSize, 60L, TimeUnit.SECONDS, SynchronousQueue())
?Ambos
FixedThreadPool
yCachedThreadPool
son males en aplicaciones muy cargadas.CachedThreadPool
es mas peligroso queFixedThreadPool
Si su aplicación está muy cargada y exige baja latencia, es mejor deshacerse de ambas opciones debido a los inconvenientes siguientes
CachedThreadPool
que se salga de control en la creación del subprocesoComo sabes que ambos son males, el mal menor no hace el bien. Prefiera ThreadPoolExecutor , que proporciona un control granular sobre muchos parámetros.
beforeExecute(Thread, Runnable)
yafterExecute(Runnable, Throwable)
fuente
¿Está seguro de que comprende cómo el sistema operativo y el hardware de su elección procesan los subprocesos? ¿Cómo asigna Java los subprocesos a los subprocesos del sistema operativo, cómo eso asigna los subprocesos a los subprocesos de la CPU, etc.? Lo pregunto porque crear 150 subprocesos dentro de ONE JRE solo tiene sentido si tiene núcleos / subprocesos de CPU masivos debajo, lo que probablemente no sea el caso. Dependiendo del sistema operativo y la RAM en uso, la creación de más de n subprocesos podría incluso provocar la terminación de su JRE debido a errores OOM. Por lo tanto, realmente debería distinguir entre los subprocesos y el trabajo a realizar por esos subprocesos, cuántos trabajos incluso puede procesar, etc.
Y ese es el problema con CachedThreadPool: no tiene sentido poner en cola el trabajo de larga ejecución en subprocesos que en realidad no se pueden ejecutar porque solo tiene 2 núcleos de CPU capaces de procesar esos subprocesos. Si termina con 150 subprocesos programados, puede crear una gran cantidad de gastos generales innecesarios para que los programadores utilizados en Java y el sistema operativo los procesen simultáneamente. Esto es simplemente imposible si solo tiene 2 núcleos de CPU, a menos que sus subprocesos estén esperando E / S o algo así todo el tiempo. Pero incluso en ese caso, muchos subprocesos crearían una gran cantidad de E / S ...
Y ese problema no ocurre con FixedThreadPool, creado, por ejemplo, con 2 + n subprocesos, donde n es razonablemente bajo, por supuesto, porque con ese hardware y los recursos del sistema operativo se utilizan con mucha menos sobrecarga para administrar subprocesos que no pueden ejecutarse de todos modos.
fuente