the Java Language Specificationによれば、作成中のオブジェクトが他のスレッドで作成されているのを見ることができないので、コンストラクタを同期化することはできません。私は確かに構築されている間、別のスレッドがオブジェクトを見ることができますので、これは、少し奇妙に思える:Javaコンストラクタを同期できないのはなぜですか?
public class Test {
public Test() {
final Test me = this;
new Thread() {
@Override
public void run() {
// ... Reference 'me,' the object being constructed
}
}.start();
}
}
が、私はこれはかなり不自然な例であることを知っているが、誰かが思い付くことができることを理論的に思えますこのようなスレッドを持つレースを防ぐために、コンストラクタを同期してマークするのが正当なより現実的なケースです。
私の質問は、Javaがコンストラクタでsynchronized修飾子を特に許可しない理由はありますか?おそらく私の上記の例に欠陥があるかもしれません。あるいは、おそらく実際には理由がなく、それは任意の設計上の決定です。どちらの場合でも、私は本当に興味があり、答えを知りたいです。
他にも、コンストラクタが完了する前に "this"リファレンスがエスケープされないようにすることを強くお勧めします。 –
@Mike Q-私はこれまでにこれを聞いたことがありますが、理由を完全に理解していません。なぜ特別な理由がありますか?オブジェクトの初期化を完了する前にこれを参照した場合、オブジェクトが発生していることがわかりましたが、コンストラクタで最後に行った場合はどうなりますか? – templatetypedef
これは本当に別の質問の対象ですが、コンストラクタで最後に行うことであっても、オブジェクトがサブクラス化されている場合、サブクラスは構築が完了していません。このクラスがfinalで、コンストラクタをチェーンしていない場合(this(...)を呼び出す)、チェーンコールの後に何か他のことをしてください。もちろん、これらの決定のいずれかが変更される可能性があります(後で2番目のコンストラクタを追加することもできます)。 – Yishai