thread - Java Singleton vs static: ¿hay un beneficio de rendimiento real?
singleton synchronized java (7)
Estoy fusionando una rama CVS y uno de los cambios más grandes es el reemplazo, dondequiera que ocurra, de un patrón Singleton con clases abstractas que tienen un bloque de inicialización estático y todos los métodos estáticos.
¿Es esto algo que vale la pena mantener ya que requerirá unir muchos conflictos, qué tipo de situación estaría buscando para que esta refactorización valga la pena?
Estamos ejecutando esta aplicación bajo Weblogic 8.1 (por lo que JDK 1.4.2)
Lo siento Thomas, déjame aclarar ...
la versión HEAD tiene el patrón Singleton tradicional (constructor privado, getInstance (), etc.)
la versión de la rama no tiene constructor, es una ''clase abstracta pública'' y modificó todos los métodos del objeto para que sean ''estáticos''. El código que solía existir en el constructor privado se mueve a un bloque estático.
Luego se cambian todos los usos de la clase, lo que causa conflictos múltiples en la fusión.
Hay algunos casos donde se realizó este cambio.
¿Ayuda esta discusión? (No sé si es tabú vincular a otro foro de programación, pero preferiría no solo citar toda la discusión =))
El veredicto parece ser que no importa lo suficiente en la mayoría de los casos, aunque técnicamente los métodos estáticos son más eficientes.
Desde un punto de vista estricto del rendimiento en el tiempo de ejecución, la diferencia es realmente insignificante. La principal diferencia entre los dos radica en el hecho de que el ciclo de vida "estático" está vinculado al cargador de clases, mientras que para el singleton es un ciclo de vida de instancia regular. Por lo general, es mejor mantenerse alejado del negocio de ClassLoader, evite algunos problemas complicados, especialmente cuando intenta volver a cargar la aplicación web.
Escribe un código para medir el rendimiento. La respuesta dependerá de la JVM (el JDK de Sun podría funcionar de manera diferente que JRockit) y los indicadores de VM que usa la aplicación.
La estática es mala para la extensibilidad ya que los campos y métodos estáticos no se pueden ampliar ni anular por subclases.
También es malo para las pruebas unitarias. Dentro de una prueba unitaria no puede evitar que los efectos secundarios de diferentes pruebas se desborden, ya que no puede controlar el cargador de clases. Los campos estáticos inicializados en una prueba unitaria serán visibles en otra o, peor aún, la ejecución simultánea de pruebas arrojará resultados impredecibles.
Singleton generalmente es un patrón aceptable cuando se usa con moderación. Prefiero usar un marco DI y dejar que eso administre mis instancias para mí (posiblemente dentro de diferentes ámbitos, como en Guice).
Según mi experiencia, lo único que importa es cuál es más fácil burlarse en las pruebas unitarias. Siempre sentí que Singleton es más fácil y natural de burlarse. Si su organización le permite usar JMockit, no importa ya que puede superar estas preocupaciones.
Si la publicación original fue la correcta y la discusión de Sun a la que se vinculó es precisa (lo que creo que podría ser), entonces creo que debe hacer una compensación entre claridad y rendimiento.
Hágase estas preguntas:
- ¿El objeto Singleton hace que lo que estoy haciendo sea más claro?
- ¿Necesito un objeto para hacer esta tarea o es más adecuado para métodos estáticos?
- ¿Necesito el rendimiento que puedo obtener al no usar un Singleton?
Yo usaría un singleton si fuera necesario para almacenar cualquier estado, y las clases estáticas de lo contrario. No tiene sentido instanciar algo, incluso una sola instancia, a menos que necesite almacenar algo.