Estoy usando un bloque de código estático para inicializar algunos controladores en un registro que tengo. Mi pregunta es, por lo tanto, ¿puedo garantizar que este bloque de código estático solo se invocará una vez cuando se cargue la clase por primera vez? Entiendo que no puedo garantizar cuándo se llamará a este bloque de código, supongo que es cuando el cargador de clases lo carga por primera vez. Me doy cuenta de que podría sincronizar en la clase en el bloque de código estático, pero supongo que esto es lo que sucede de todos modos.
Ejemplo de código simple sería;
class FooRegistry {
static {
//this code must only ever be called once
addController(new FooControllerImpl());
}
private static void addController(IFooController controller) {
// ...
}
}
o debería hacer esto;
class FooRegistry {
static {
synchronized(FooRegistry.class) {
addController(new FooControllerImpl());
}
}
private static void addController(IFooController controller) {
// ...
}
}
Respuestas:
Sí, los inicializadores estáticos de Java son seguros para subprocesos (use su primera opción).
Sin embargo, si desea asegurarse de que el código se ejecute exactamente una vez, debe asegurarse de que la clase solo sea cargada por un único cargador de clases. La inicialización estática se realiza una vez por cargador de clases.
fuente
Este es un truco que puedes usar para la inicialización diferida
o para pre Java 5.0
Como el bloque estático en SingletonHolder se ejecutará una vez de manera segura para subprocesos, no necesita ningún otro bloqueo. La clase SingletonHolder solo se cargará cuando llame a instancia ()
fuente
En circunstancias habituales, todo en el iniciador estático sucede, antes de todo lo que usa esa clase, por lo que la sincronización no suele ser necesaria. Sin embargo, la clase es accesible para cualquier cosa que llame el intiailizador estático (incluso hacer que se invoquen otros inicializadores estáticos).
Una clase puede ser cargada por una clase cargada pero no necesariamente inicializada de inmediato. Por supuesto, una clase puede cargarse mediante múltiples instancias de cargadores de clases y, por lo tanto, convertirse en múltiples clases con el mismo nombre.
fuente
Sí, más o menos
Un
static
inicializador solo se llama una vez, por lo que, según esa definición, es seguro para subprocesos: necesitaría dos o más invocaciones delstatic
inicializador para incluso obtener la contención de subprocesos.Dicho esto, los
static
inicializadores son confusos en muchas otras formas. Realmente no hay un orden específico en el que se llaman. Esto se vuelve realmente confuso si tiene dos clases cuyosstatic
inicializadores dependen el uno del otro. Y si usa una clase pero no usa lostatic
que configurará el inicializador, no está garantizado que el cargador de clases invoque el inicializador estático.Finalmente, tenga en cuenta los objetos con los que está sincronizando. Me doy cuenta de que esto no es realmente lo que estás preguntando, pero asegúrate de que tu pregunta no sea realmente si necesitas hacer un
addController()
hilo seguro.fuente
Sí, los inicializadores estáticos se ejecutan solo una vez. Lea esto para más información .
fuente
Básicamente, dado que desea una instancia singleton, debe hacerlo más o menos a la antigua y asegurarse de que su objeto singleton se inicialice una vez y solo una vez.
fuente