java - pelicula - thread pool c#
¿Por qué ScheduledThreadPoolExecutor solo acepta un número fijo de subprocesos? (3)
Como el por qué, tampoco lo sé. Pero puedo imaginar.
La cantidad de recursos de una computadora es limitada. No todos los recursos pueden ser manejados concurrentemente tampoco.
Si varios procesos cargan archivos al mismo tiempo, se cargarán más lentamente que si se cargaran de forma secuencial (al menos en un disco duro).
Un procesador también tiene soporte limitado para manejar múltiples subprocesos simultáneamente. En algún momento, el sistema operativo o JVM pasarán más tiempo cambiando de hilos, que los hilos que pasan ejecutando su código.
Esa es una buena razón para que el ScheduledThreadPoolExecutor
se diseñe de la manera que es. Puede poner cualquier cantidad de trabajos en la cola, pero nunca se ejecutan más trabajos al mismo tiempo que pueden ejecutarse de manera eficiente. Depende de usted para equilibrar eso, por supuesto.
Si sus tareas están vinculadas a IO, establecería un tamaño de grupo pequeño y, si están vinculados a la CPU, un poco más grande (32 o más). También puede hacer múltiples ScheduledThreadPoolExecutor
s, uno para tareas enlazadas de IO y uno para tareas enlazadas de CPU.
Puedo imaginar algunas tareas programadas para que tomen mucho tiempo y ScheduledThreadPoolExecutor
crearía subprocesos adicionales para las otras tareas que deben ejecutarse, hasta que se alcance un número máximo de subprocesos.
Pero parece que solo puedo especificar un número fijo de subprocesos para el grupo, ¿por qué es así?
De acuerdo con Java Concurrency In Practice, existen las siguientes desventajas de la creación de subprocesos ilimitados:
Hilo ciclo de vida por encima
La creación de hilos y el desmontaje no son gratuitos. La creación de hilos lleva tiempo y requiere cierta actividad de procesamiento por parte de la JVM y el sistema operativo.
Consumo de recursos
Los hilos activos consumen recursos del sistema, especialmente memoria. Cuando hay más subprocesos ejecutables que procesadores disponibles, los subprocesos permanecen inactivos. Tener muchos subprocesos inactivos puede ocupar una gran cantidad de memoria, ejercer presión sobre el recolector de basura y tener muchos subprocesos que compitan por las CPU también puede imponer otros costos de rendimiento. Si tiene suficientes subprocesos para mantener a todas las CPU ocupadas, la creación de más subprocesos no ayudará e incluso puede hacer daño.
Estabilidad
Hay un límite en la cantidad de subprocesos que se pueden crear. El límite varía según la plataforma y se ve afectado por factores que incluyen los parámetros de invocación de JVM, el tamaño de pila solicitado en el constructor de subprocesos y los límites de los subprocesos colocados por el sistema operativo subyacente. Cuando alcanza este límite, el resultado más probable es un OutOfMemoryError. Tratar de recuperarse de tal error es muy arriesgado; Es mucho más fácil estructurar su programa para evitar alcanzar este límite.
Hasta cierto punto, más subprocesos pueden mejorar el rendimiento, pero más allá de ese punto, crear más subprocesos solo ralentiza la aplicación, y crear un subproceso demasiados puede hacer que toda la aplicación se bloquee de forma horrible. La forma de mantenerse fuera de peligro es colocar un límite en la cantidad de subprocesos que crea su aplicación y probar su aplicación a fondo para asegurarse de que, incluso cuando se alcanza este límite, no se quede sin recursos.
La creación de subprocesos sin límites puede parecer que funciona bien durante la creación de prototipos y el desarrollo, con problemas que surgen solo cuando la aplicación está implementada y bajo una gran carga.
Mientras buscaba más sobre SchecduledThreadPoolExecutor, encontré este link . Este enlace explica que SchecduledThreadPoolExecutor resuelve muchos problemas de la clase Timer. Y también la razón para introducir SchecduledThreadPoolExecutor fue reemplazar Timer (debido a varios problemas con Timer). Creo que la razón para el número fijo de subprocesos pasados a SchecduledThreadPoolExecutor está en uno de los problemas que resuelve esta clase. es decir
La clase Timer comienza solo un hilo. Si bien es más eficiente que crear un subproceso por tarea, no es una solución óptima. La solución óptima puede ser utilizar un número de subprocesos entre un subproceso para todas las tareas y un subproceso por tarea. En efecto, la mejor solución es colocar las tareas en un grupo de subprocesos. El número de subprocesos en el grupo debe ser asignable durante la construcción para permitir que el programa determine el número óptimo de subprocesos en el grupo.
Así que, en mi opinión, aquí es donde viene el caso de uso para SchecduledThreadPoolExecutor. En su caso, debe poder decidir el valor óptimo dependiendo de las tareas que planea programar y el tiempo que estas tareas requieren para finalizar. Si tengo 4 tareas de ejecución prolongadas que están programadas para el mismo tiempo, preferiría que el tamaño de mi grupo sea mayor que 4 si se ejecutan otras tareas durante el mismo tiempo. También preferiría separar las tareas de ejecución prolongada en diferentes ejecutores como se indicó en las respuestas anteriores.
Espero que esto ayude :)