mvc - patron singleton java
¿Cómo sirve Singleton Bean a la solicitud concurrente? (5)
He visto muchas advertencias para mantener sin estado los frijoles singleton compartidos y quería presentar un caso de uso en el que un singleton con estado en un frijol de respaldo de aplicaciones web tenga sentido.
Tengo una aplicación web administrativa que, a petición, consulta datos de usuario de dos sistemas separados (un CRM y un Administrador de Activos Digitales - DAM), compara los registros y actualiza el DAM de acuerdo con su API. Esto a veces lleva mucho tiempo si hay muchas actualizaciones. La interfaz de usuario web muestra el estado de las actualizaciones en tiempo real, ya que el navegador sondea el bean de respaldo con ajax cada segundo para mostrar una barra de progreso y cuántas cuentas de usuario ha procesado. La IU también proporciona un botón para iniciar el proceso de sincronización y un botón para detenerlo. El botón de sincronización está inicialmente habilitado y el botón de parada no se procesa. Después de que el usuario haga clic en el botón de inicio, el botón de inicio se desactiva y el botón de detención se habilita.
Mientras la sincronización está activa, quiero que diferentes clientes (diferentes usuarios en el teclado que usan la aplicación web en sus navegadores separados) vean el mismo estado, es decir, la barra de progreso y la cantidad de cuentas de usuario procesadas y los estados del botón. Esto es importante porque no tiene sentido iniciar un segundo proceso de sincronización mientras uno ya está en proceso.
Tengo una pregunta sobre cómo Singleton Beans atiende las solicitudes concurrentes en detalle.
He buscado en StackOverflow con respecto a esta pregunta. Este es un enlace de ejemplo de stackoverflow , pero solo encontré detalles de alto nivel. Quiero detalles completos sobre cómo un bean singleton sirve solicitudes concurrentes y cómo el procesador del sistema verá esas solicitudes.
He investigado sobre el manejo de solicitudes concurrentes en el procesador del sistema en línea. Dijeron que el propio procesador tiene un programador y ese programador decidirá qué solicitud se procesa.
Está bien. Si supongo que tengo más de un procesador central, ¿cómo maneja el programador las solicitudes simultáneas?
¿Puede alguien explicarme el proceso paso a paso sobre cómo un bean singleton servirá solicitudes simultáneas en la JVM y el sistema?
Déjame explicarte con un ejemplo concreto. Tengo una clase como Sports
:
class Sports {
public void playFootball() {
}
public void playVolleyBall() {
}
}
playFootball
dos solicitudes. La primera solicitud es ejecutar el método playFootball
en la instancia de singleton creada de la clase Sports
. Al mismo tiempo, otra solicitud está ejecutando el método playVolleyBall
en la misma instancia de singleton creada de la clase Sports
.
¿Cómo es posible con una instancia de singleton?
Para saber en detalle ¿Cómo sirve Singleton Bean a la solicitud concurrente? Tienes que saber las siguientes cosas sobre los frijoles de primavera
Alcances de frijol
Spring tiene diferentes ámbitos de bean (por ejemplo, Prototype, Singleton, etc.) pero todos estos ámbitos se aplican cuando se crea el bean. Por ejemplo, se creará un bean de ámbito "prototipo" cada vez que este bean se "inyecte". mientras que un bean de alcance "singleton" se creará una vez y se compartirá dentro del contexto de la aplicación.
El ámbito "singleton" es el alcance predeterminado de Spring Bean.Creación de frijol
Todo el ciclo de vida de Spring Bean es administrado por Spring Container (es decir, ApplicationContext / BeanFacotry). Spring Container remite internamente la definición de bean (es decir, la base de anotaciones de base de anotaciones) para crear instancias reales de la clase definida por esa definición de bean. ahora, cuando Spring Container se inicia, se refiere a la definición de bean e instata todo el bean definido.
Pedir el frijol.
Ahora, cuando su objeto realice una solicitud al bean, Spring Container entregará el bean que ya se haya inicializado.
Tutorial de primavera 11 - Entendiendo los alcances de los frijoles
Espero que esto te ayudará...
Saravan Kumar,
Entiendo la motivación detrás de tu pregunta. Antes de comenzar a trabajar en compiladores, también tenía un deseo muy similar de conocer los aspectos internos de la Máquina Virtual de Java.
En primer lugar, estoy impresionado por su pregunta. Tiene que haber un par de puntos de distinción y comprensión para resolver su pregunta. En primer lugar: un patrón Singleton, o algunas veces llamado anti-patrón, asegura que solo haya una instancia de esta clase disponible para la JVM. Esto significa que esencialmente estamos introduciendo un estado global en una aplicación. Sé que entiendes esto, pero es solo un punto de aclaración.
Ahora los internos.
Cuando creamos una instancia de una clase, estamos creando un objeto que reside en la memoria compartida de JVM. Ahora estos hilos están ejecutando de manera independiente el código que opera en estas instancias. Cada subproceso tiene una memoria de trabajo, en la que guarda datos de la memoria principal que se comparten entre todos los subprocesos. Aquí es donde reside la referencia al objeto Singleton que ha creado. Esencialmente, lo que está sucediendo es que el código de byte que se generó y es representativo del objeto singleton que creó se está ejecutando en cada uno de estos subprocesos.
Ahora los aspectos internos de cómo sucede esto es como sigue:
Cada subproceso de máquina virtual de Java tiene una pila de máquina virtual de Java privada, creada al mismo tiempo que el subproceso. Ahora, la máquina virtual de Java tiene un montón que se comparte entre todos los subprocesos de la máquina virtual de Java. El montón es el área de datos de tiempo de ejecución desde la que se asigna la memoria para todas las instancias de clase y matrices. El montón se crea en el inicio de la máquina virtual. Cuando el subproceso solicita la instancia de Singleton, apuntará a una referencia en el montón donde reside el código de byte para este Singleton. Ejecutará el código apropiado, en su caso ejecutará el primer método para la primera solicitud y el segundo método para la segunda solicitud. Puede hacer esto porque no hay bloqueos o restricciones que impidan que el compilador apunte el contador del programa al área en el montón donde se asigna esta instancia. La única restricción que la clase Singleton pone en la Máquina Virtual Java es que solo puede tener una instancia en el montón de esta clase. Eso es simplemente eso. Aparte de eso, puede referirse a él 100 veces desde su método, el compilador apuntará al mismo código de bytes y simplemente lo ejecutará. Esta es la razón por la que normalmente queremos que la clase Singleton sea sin estado, porque si cualquier subproceso accede a ella, no queremos que las variables internas sean mutadas debido a la falta de control de concurrencia.
¡Por favor hazme saber si tienes preguntas!
Singleton es un alcance de frijol. Tienes que manejar eso como servir para el acceso de múltiples hilos. Puede utilizar la sincronización o paquetes simultáneos. Ref .: ¿Los frijoles singleton de primavera son seguros para el hilo?
Para solicitudes concurrentes, un solo bean servirá para solicitudes mutliple una por una.
Un frijol singleton ideal no debe mantener ningún estado. Eso significa que no tendrá ninguna variable que almacene nada específico de la solicitud que está atendiendo.
Por lo tanto, un bean singleton simplemente tendrá un código sin estado (por ejemplo, métodos de controlador) que pueden ejecutarse simultáneamente para múltiples solicitudes sin ningún problema de concurrencia.
Por ejemplo, si lo siguiente fue su frijol Singleton:
@Service
public class Calculator {
public int sum(int a, int b) {
return a + b;
}
}
En términos simples, cuando dos "solicitudes" invocan el método de sum
del bean al mismo tiempo, eso significaría que el método de sum
se ejecutaría simultáneamente en dos subprocesos diferentes. Por lo tanto, tendrán su propio contexto de ejecución que no se superpondrá entre sí. Esto les permitiría correr con seguridad.
Si el mismo bean tuviera el siguiente estado:
@Service
public class Calculator {
int incrementalMultiplier = 0;
public int mulitply(int a, int b) {
incrementalMultiplier++;
return a * b * incrementalMultiplier;
}
}
Esto podría causar problemas cuando se atienden dos solicitudes al mismo tiempo porque incrementalMultiplier
es el estado de nivel de objeto que compartirán las dos solicitudes (subprocesos) y, por lo tanto, podría producir resultados inesperados.
En resumen, un singleton sin estado podrá atender dos solicitudes al mismo tiempo porque estarán en subprocesos diferentes.