シングルトンパターンは、最も簡単に理解しやすく、デザインパターンで手書きのコードを執筆する最も簡単な方法ですが、多くの知識ポイントが関係していないため、インタビューの質問としてよく使用されます。一般的に、シングルトンは5つの方法で書かれています:怠zy、空腹、ダブルチェックロック、静的な内部クラス、列挙。学習プロセスを記録するために、ここにいくつかの一般的なシングルトンライティング方法が編集されています。
ブロンズ5 :(怠zy-loadedですが、スレッドは安全ではありません)
シングルトンパターンの実装について尋ねられたとき、多くの人々の最初の反応は、教科書の同じ教えを含む次のコードを書くことです。
パブリッククラスシングルトン{プライベート静的シングルトンインスタンス; private singleton(){} public static singleton getInstance(){if(instance == null){instance = new Singleton(); } returnインスタンス; }}このコードはシンプルで簡単で、遅延ロードモードを使用しますが、スレッドは安全ではありません。マルチスレッド環境でgetInstance()メソッドを呼び出すと、複数のスレッドがIFステートメントのプログラムコードブロックを入力する可能性があります。
怠zyなスタイル:同期(怠zy-ロード、スレッドセーフ、しかし効率的ではない)
上記の問題を解決するために、最も簡単な方法は、getInstance()メソッド全体を同期して設定することです。
パブリッククラスシングルトン{プライベート静的シングルトンインスタンス; private singleton(){} public static同期Singleton getInstance(){if(instance == null){instance = new Singleton(); } returnインスタンス; }}スレッドセーフで遅延した負荷ですが、効率的ではありません。なぜなら、getInstance()メソッドを呼び出すスレッドはいつでもあるからです。ただし、同期された操作は、最初の呼び出し、つまりSingletonインスタンスオブジェクトが初めて作成された場合にのみ必要です。このパターンにより、Singletonが作成された後でも、1つのスレッドのみがGetInstance()メソッドにアクセスし、潜在的なパフォーマンスの問題につながる可能性があります。これにより、ダブルチェックロックが発生します。
空腹のスタイル:静的な最終フィールド(怠lazy-loaded)
シングルトンのインスタンスは静的な最終として宣言され、クラスが初めてメモリにロードされると初期化されるため、この方法は非常に簡単です。したがって、インスタンスオブジェクトを作成することはスレッドセーフ(JVM実装によって保証)です。
パブリッククラスのシングルトン{//プライベート静的最終シングルトンインスタンス= new Singleton(); private singleton(){} public static singleton getInstance(){//静的ファクトリーリターンインスタンスを備えたSingleton; }}これは怠zyなロードモードではありません。インスタンスは、クライアントがgetInstance()メソッドを呼び出していない場合でも、クラスのロード後に最初から初期化されます。これにより、いくつかの使用制限が発生します。たとえば、Singletonインスタンスの作成は、パラメーターまたは構成ファイルに依存します。 getInstance()の前に、このシングルトンライティング方法を使用しないように、パラメーターを設定するために特定の方法を呼び出す必要があります。同様の方法は次のとおりです。
パブリッククラスシングルトン{public static final singleton instance = new Singleton(); //パブリックファイナルフィールドプライベートシングルトン(){}} // <EffencialJava>ページ14が2つの違いを伝えているシングルトンダブルチェックロック +揮発性(怠zy、スレッドセーフ、しかしあいまいな)
再確認されたロックパターンは、同期ブロックを使用してロックする方法です。プログラマーは、2つのチェックインスタンス== nullが同期ブロックの外側と同期ブロックの内側にあるため、ダブルチェックロックと呼びます。同期ブロックをもう一度確認する必要があるのはなぜですか?同期ブロックの外側にある場合、複数のスレッドが入力される可能性があるため、同期ブロックで二次検証が実行されない場合、複数のインスタンスオブジェクトが生成されます。
public static singleton getSingleton(){if(instance == null){//シングルチェックed synchronized(singleton.class){if(instance == null){// double checked instance = new Singleton(); }}} return instance;}このコードは完璧に見えますが、残念ながら問題があります。主なことは、文intance = new Singleton()です。これは原子操作ではありません。実際、JVMのこの文は、ほぼ3つのことを行います。
ただし、JVMのJITコンパイラには、命令の並べ替えが最適化されています。言い換えれば、上記の2番目と3番目のステップの順序を保証することはできず、最終的な実行命令は1-2-3または1-3-2である場合があります。後者の場合、3と2の実行が実行されない前に、スレッド2で先取りされます。現時点では、インスタンスはすでに非ヌル(初期化されていません)であるため、スレッド2はインスタンスを直接返してから使用してから、自然にエラーを報告します。これを行うには、インスタンス変数を揮発性として宣言する必要があります。
パブリッククラスシングルトン{プライベート揮発性静的シングルトンインスタンス; //揮発性のプライベートシングルトン(){} public static singleton getSingleton(){if(instance == null){synchronized(singleton.class){if(instance == null){instance = new singleton(); }} return instance; }}ただし、Java 1.5の前にバージョンの揮発性のデュアルチェックロックにはまだ問題があることに注意することが重要です。この問題はJava 1.5でのみ修正されたため、その後揮発性を使用できます。
静的インナークラス:IODH、初期化オンデマンドホルダー
このパターンは、Javaの静的な内部クラスとマルチスレッドデフォルトの同期ロック知識を組み合わせて、レイテンシの負荷とスレッドの両方の安全性を巧みに実装します。
パブリッククラスSingleton {private Singleton(){} private static class lazyholder {private static final singleton instance = new Singleton(); } public static singleton getInstance(){// Wikipedia return lazyholder.instance; }}静的な内部クラスは、その外側クラスの静的部分と同等です。そのオブジェクトは、外部クラスオブジェクトに依存していないため、直接作成できます。静的な内部クラスは、初めて使用される場合にのみ再現されます。
マルチスレッドデフォルトの同期ロック
私たち全員が知っているように、マルチスレッド開発では、並行性の問題を解決するために、主に同期を使用して同期制御のためにミューテックスを追加することです。しかし、場合によっては、JVMはすでにあなたのために同期を暗黙的に実行しており、これらの場合、同期制御を手動で実行する必要はありません。これらの状況は次のとおりです。
1.静的イニシャルイザーによる初期化の場合(静的フィールドの初期イザーまたは静的{}ブロック)
2。最終フィールドにアクセスするとき
3。スレッドを作成する前にオブジェクトを作成するとき
4。スレッドがオブジェクトを見ることができるとき、それは処理されます
列挙
Java 1.5から始めて、単一の要素を含む列挙タイプを書くだけです。
Public Enum Singleton {instance;}この方法はパブリックドメイン法と機能的に類似していますが、より簡潔であり、複雑なシリアル化または反射攻撃に直面しても、複数のインスタンス化を完全に防ぐシリアル化メカニズムを無料で提供します。このアプローチは広く採用されていませんが、列挙タイプの単一要素がシングルトンを実装する最良の方法になりました。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -
1.静的ファイナルの詳細は何ですか
2。順番の静的フィールドと静的コードブロックでの割り当て初期化は?
3.静的な内部クラスのシングルトンパターンの書き方
4. Java EEのデザインパターン分析とアプリケーションの例は、本当に怠zyな効果がありますか?
上記はこの記事のすべての内容です。この記事の内容が、すべての人の勉強や仕事に役立つことを願っています。また、wulin.comをもっとサポートしたいと思っています!