Java facilita la creación de nuevos subprocesos, y los programas crean más subprocesos de los que la CPU puede procesar en paralelo. Digamos que tenemos una carretera de dos carriles (dos núcleos de una CPU), y 10 autos quieren usar la carretera al mismo tiempo. Naturalmente, esto no es posible, pero piense en cómo se maneja actualmente esta situación. Los semáforos son unidireccionales. Los semáforos permiten que un número controlado de automóviles ingresen a la carretera y hacen que el tráfico use la carretera de manera ordenada.
En computadoras, este es un planificador. El planificador asigna el hilo a un núcleo de CPU para ejecutarlo. En el mundo moderno del software, el sistema operativo cumple esta función de programar tareas (o subprocesos) en la CPU.
En Java, cada subproceso se asigna a un subproceso del sistema operativo por la JVM (casi todas las JVM hacen eso). Con los hilos superando en número a los núcleos de CPU, se asigna un montón de tiempo de CPU para programar los hilos en el núcleo. Si un subproceso pasa al estado de espera (por ejemplo, esperando que responda una llamada de la base de datos), el subproceso se marcará como en pausa y se asignará un subproceso separado al recurso de la CPU. Esto se llama cambio de contexto (aunque se requiere mucho más para hacerlo). Además, cada subproceso tiene algo de memoria asignada y el sistema operativo solo puede manejar un número limitado de subprocesos.
Considere una aplicación en la que todos los hilos están esperando que responda una base de datos. Aunque la computadora de la aplicación está esperando la base de datos, se están utilizando muchos recursos. Con el auge de las aplicaciones a escala web, este modelo de subprocesos puede convertirse en el principal cuello de botella para la aplicación.
Una solución es hacer uso de la programación reactiva. Brevemente, en lugar de crear subprocesos para cada tarea concurrente (y tareas de bloqueo), un subproceso dedicado (llamado bucle de eventos) examina todas las tareas que se asignan a subprocesos en un modelo no reactivo y procesa cada uno de ellos en el mismo Núcleo de la CPU. Por lo tanto, si una CPU tiene cuatro núcleos, puede haber múltiples bucles de eventos pero sin exceder el número de núcleos de CPU. Este enfoque resuelve el problema del cambio de contexto, pero introduce mucha complejidad en el programa mismo. Este tipo de programa también se escala mejor, que es una razón por la que la programación reactiva se ha vuelto muy popular en los últimos tiempos. Vert.x es una de esas bibliotecas que ayuda a los desarrolladores de Java a escribir código de manera reactiva.
Por lo tanto, el modelo de subprocesos por tarea es fácil de implementar pero no escalable. La programación reactiva es más escalable, pero la implementación es un poco más complicada. Un gráfico simple que representa la complejidad del programa frente a la escalabilidad del programa se vería así:
Lo que necesitamos es un punto óptimo como se menciona en el diagrama anterior (el punto verde), donde obtenemos una escala web con una complejidad mínima en la aplicación. Y ese es Project Loom.
En lugar de asignar un subproceso del sistema operativo por subproceso Java (modelo JVM actual), Project Loom proporciona que múltiples subprocesos puedan ser ejecutados por un proceso del sistema operativo. Este enfoque proporciona un mejor uso (los subprocesos del sistema operativo siempre funcionan y no esperan) y mucho menos el cambio de contexto.
Project Loom provee concurrencia ligera de alto rendimiento y fácil de usar y nuevos modelos de programación en la plataforma Java.
El núcleo del Proyecto Loom involucra Continuations and Fibers. Pero esa historia será contada en otro post ...
Dejo link:
https://developers.redhat.com/blog/2019/06/19/project-loom-lightweight-java-threads/