Según the Java Language Specification, los constructores no se pueden marcar sincronizados porque otros subprocesos no pueden ver el objeto que se está creando hasta que la hebra que lo creó haya terminado. Esto parece un poco extraño, porque de hecho puede tener otro hilo de ver el objeto mientras se está construyendo:¿Por qué no se pueden sincronizar los constructores de Java?
public class Test {
public Test() {
final Test me = this;
new Thread() {
@Override
public void run() {
// ... Reference 'me,' the object being constructed
}
}.start();
}
}
sé que este es un ejemplo bastante artificial, pero parece que en la teoría de que alguien pueda llegar a una Caso más realista donde marcar al constructor sincronizado sería legítimo para evitar carreras con hilos como este.
Mi pregunta es esta: ¿hay alguna razón por la cual Java específicamente desaprobaría el modificador sincronizado en un constructor? Tal vez mi ejemplo anterior es defectuoso, o tal vez realmente no hay ninguna razón y es una decisión de diseño arbitraria. En cualquier caso, tengo mucha curiosidad y me encantaría saber la respuesta.
Como comentario adicional, se recomienda no permitir que la referencia "this" escape antes de que el constructor haya finalizado. –
@Mike Q- He escuchado esto antes, pero no entiendo completamente por qué. ¿Hay alguna razón en particular por qué? Pude ver que ocurrían cosas malas si le dabas una referencia antes de que terminaras de inicializar el objeto, pero ¿y si es lo último que haces en el constructor? – templatetypedef
es realmente el tema de otra pregunta, pero incluso si es lo último que haces en el constructor, si el objeto está subclasificado, entonces la subclase no ha terminado de construirse. Si esta clase es final, y no encadenas constructores (llamando a esto (...)) y haces algo más después de la llamada en cadena y es lo último que haces, está bien. Excepto por supuesto que cualquiera de esas decisiones podría cambiar (podría agregar un segundo constructor más adelante). – Yishai