Editar:
Hrm. Mientras leo esto, es técnicamente incorrecto, pero está bien en la práctica con algunas advertencias. Solo los campos finales se pueden inicializar de forma segura una vez y acceder a ellos en múltiples hilos sin sincronización.
Los subprocesos iniciados diferidos pueden sufrir problemas de sincronización de varias formas. Por ejemplo, puede tener condiciones de carrera de constructor donde la referencia de la clase ha sido exportada sin la clase en sí se está inicializando completamente.
Creo que depende en gran medida de si tiene o no un campo primitivo o un objeto. Los campos primitivos que se pueden inicializar varias veces en los que no te importa que varios hilos hagan la inicialización funcionarían bien. Sin embargo, la inicialización de estilo HashMap
de esta manera puede ser problemática. Incluso los valores long
en algunas arquitecturas pueden almacenar las diferentes palabras en varias operaciones, por lo que pueden exportar la mitad del valor, aunque sospecho que un long
nunca cruzaría una página de memoria, por lo que nunca sucedería.
Creo que depende en gran medida de si es o no una aplicación tiene ningún barreras de memoria - cualquier synchronized
bloques o acceso a volatile
campos. El diablo está ciertamente en los detalles aquí y el código que hace la inicialización perezosa puede funcionar bien en una arquitectura con un conjunto de códigos y no en un modelo de subproceso diferente o con una aplicación que se sincroniza raramente.
He aquí una buena pieza en campos finales como comparación:
http://www.javamex.com/tutorials/synchronization_final.shtml
A partir de Java 5, un uso particular de la palabra clave final es un arma muy importante ya menudo pasado por alto en su arsenal de concurrencia. Esencialmente, el final se puede usar para asegurarse de que cuando se construye un objeto, otro subproceso que accede a ese objeto no vea ese objeto en un estado parcialmente construido, como podría ocurrir de otro modo.Esto es porque cuando se usa como un atributo en las variables de un objeto, final tiene la siguiente característica importante como parte de su definición:
Ahora, incluso si el campo está marcado como final, si se trata de una clase, puede modificar los campos dentro de la clase. Este es un problema diferente y aún debe tener sincronización para esto.
no temas las lecturas volátiles. la inicialización de clases, es decir, el código modificable es la única forma portátil de hacerlo sin volátiles. La declaración es incorrecta frente a la arquitectura de la CPU que permite reordenar las escrituras.En x86 y Sparc TSO, la lectura volátil es gratuita, por lo que no tiene sentido jugar con un hacker. – bestsss