Javaプログラムでは、いくつかのハイオーバーヘッドオブジェクトの初期化操作を延期する必要がある場合があり、これらのオブジェクトを使用する場合にのみ初期化されます。これは、遅延初期化または怠zyなロードと呼ばれます
危険な遅延初期化を見てください:
スレッドAが1を実行した後、オブジェクトインスタンスがnullであり、新規の準備ができていることがわかりますが、スレッドBは最初に新しいため、エラーが発生します。
同期ロックを使用して、正しさを確保することができます。
しかし、メソッド全体を同期することは高すぎるため、人々はダブルチェックロックを思いつきました。
最小範囲で使用される同期ロックは、ダブルチェックを使用して目的を達成しているようですが、これには問題があります。Aaがスレッド4を実行すると、スレッドBの7がまだ実行されておらず、スレッドAはインスタンス!= nullを決定します。スレッドBの7はまだ実行されていないのに、なぜこれが起こるのですか?
新しいinstance()の基礎となる重要な実装をご覧ください。
実際、最初に1つのメモリを割り当ててから、オブジェクトを初期化してインスタンスを設定することです。次に、ここには再注文があり、2と3の順序が交換される場合があります。
したがって、Bがまだ7を実行すると、Aはインスタンスオブジェクトが初期化されたことを4で決定します。インスタンスがctorinstance(メモリ)の前に呼び出される場合、エラーが発生します。
2つの解決策があります。
1.インスタンスオブジェクトを揮発性として宣言すると、2と3の並べ替えを禁止します
2。クラスの初期化に基づくソリューションの使用:JVMは、クラスの初期化段階でクラス初期化を実行します(つまり、クラスがロードされ、スレッドで使用される前)。存在する
実行クラスの初期化中、JVMはロックを取得します。このロックは、同じクラスの初期化を複数のスレッドで同期させることができます
クラスの初期化に基づくスキームの実装コードがより簡単であることがわかります。しかし、揮発性に基づくデュアルチェックロックスキームには追加の利点があります。静的フィールドの初期化を遅らせることに加えて、インスタンスフィールドの初期化を遅らせることもできます。フィールド遅延初期化により、クラスの初期化またはインスタンスの作成のオーバーヘッドが減少しますが、遅延したフィールドにアクセスするオーバーヘッドが増加します。ほとんどの場合、通常の初期化は遅延初期化よりも優れています。たとえばフィールドにスレッドセーフの遅い初期化を使用する必要がある場合は、上記の揮発性ベースの遅延初期化スキームを使用してください。静的フィールドにスレッドセーフ後期初期化を使用する必要がある場合は、上記のクラスベースの初期化スキームを使用してください。
要約します
上記は、編集者によって導入されたJavaダブルチェックロックの実装コードです。私はそれが誰にでも役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は、すべての人に時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!