Pourquoi ne peut-Java constructeurs être synchronisées?

Selon la Spécification du Langage Java, les constructeurs ne peuvent pas être marquées synchronisé parce que les autres threads ne peuvent pas voir l'objet en cours de création jusqu'à ce que le fil de la création, il l'a terminé. Cela semble un peu bizarre, parce que je ne peux en effet avoir un autre thread voir l'objet, alors qu'il est en cours de construction:

public class Test {
    public Test() {
       final Test me = this;
       new Thread() {
           @Override
           public void run() {
               //... Reference 'me,' the object being constructed
           }
       }.start();
    }
}

Je sais que c'est un joli exemple artificiel, mais il semble que dans la théorie que quelqu'un pourrait trouver une façon plus réaliste cas où le marquage le constructeur synchronisé serait légitime afin de prévenir les courses avec son fils comme celui-ci.

Ma question est la suivante: est-il une raison que Java serait d'interdire le modificateur synchronized sur un constructeur? Peut-être que mon exemple ci-dessus est erronée, ou peut-être il n'y a vraiment aucune raison et c'est une conception arbitraire de la décision. Dans les deux cas, je suis très curieux et j'aimerais vraiment connaître la réponse.

  • En aparté, il est fortement recommandé de ne pas autoriser le "ce" de référence pour s'échapper avant que le constructeur a terminé.
  • Q - j'ai entendu cela avant, mais ne comprennent pas bien pourquoi. Est-il une raison particulière? J'ai pu voir de Mauvaises Choses qui se passe si vous avez donné une référence à cette avant que vous avez terminé l'initialisation de l'objet, mais que si c'est la dernière chose que vous faites dans le constructeur?
  • c'est vraiment l'objet d'une autre question, mais même si c'est la dernière chose que vous faites dans le constructeur, si l'objet est sous-classé, puis la sous-classe n'a pas fini de construire. Si cette classe est définitive, et vous n'avez pas la chaîne de constructeurs (à l'appel de cette(...)) et de faire autre chose après la chaîne appel et c'est la dernière chose que vous faites, de son amende. Sauf, bien sûr, que l'une de ces décisions sont susceptibles de changer (vous pouvez ajouter un deuxième constructeur plus tard).
  • C'est beaucoup plus clair si vous citer ce que le JLS dit en réalité: "Il n'y a pas de pratique besoin d'un constructeur de la synchronisation, car elle permettrait de verrouiller l'objet en cours de construction, qui est normalement ne sont pas disponibles pour les autres threads jusqu'à ce que tous les constructeurs de l'objet, ont terminé leur travail."
  • voir ibm.com/developerworks/java/library/j-jtp0618.html pour plus de détails
  • De la Java Tutoriel (lien) "Attention: Lors de la construction d'un objet qui sera partagé entre les threads, faire très attention à ce qu'une référence à l'objet n'a pas de "fuite" prématurément. Par exemple, supposons que vous voulez maintenir une Liste appelée instances contenant toutes les instances d'une classe. Vous pourriez être tenté d'ajouter la ligne suivante à votre constructeur: instances.add(this); Mais alors les autres threads peuvent utiliser des instances d'accès à l'objet avant la construction de l'objet est terminée."
  • En plus de la remarque précédente, la Java Tutoriel dit, dans la même leçon, que vous ne pouvez pas utiliser le " synchronisé mot-clé dans un constructeur, puis il indique le message d'avertissement dans le commentaire précédent. Cela semble contradictoire pour moi, et j'espère que, dans l'avenir, les constructeurs seront synchronisés par défaut sur l'objet créé. C'est ce qui semble le plus raisonnable à mon humble avis, car, autrement, vous accédez à un objet dans un état incohérent.