シングルトンパターンは、23 個の設計パターンの 1 つであり、何度呼び出しても同じオブジェクトを返すことを目的としています。その特徴は、コンストラクターがプライベート化されていることです。
これは 2 つの構造に分かれており、1 つは怠け者スタイル、もう 1 つはハングリーマン スタイルです。それぞれに利点と欠点があります。コードは次のとおりです。
public class Single { private static Single = new Single(); public Single getInstance() { return single; }
上記のプログラムから、同じオブジェクトをロードするという目的は実際に達成されていることがわかりますが、このクラスにそのようなメソッドが複数ある場合、それらのメソッドは使用できない可能性があります。このオブジェクト内で使用するとメモリの無駄が発生します。したがって、遅延シングルトン パターンが出現しました。コードは次のとおりです。
public class Single { private static Single = null; private Single() { } public Single getInstance() { if(single==null){ single = new Single() } }
このように、オブジェクトは実際に呼び出したときにのみ新しくなりますが、これには問題があります。
上記の 2 番目のコードが初めてロードされるときに 2 つのスレッドによって呼び出される場合、2 つの異なるオブジェクトが生成されるため、スレッドアンセーフになります。このとき、ロック後のコードである Lock を追加することを考えます。は次のとおりです。
public class Single { private static Single = null; private Single() { } public synchronized Single getInstance() { if (single == null) { single = new Single() } }
これによりスレッドの安全性は確保されますが、ロック メソッドが多くのことを実行する必要がある場合、このメソッドの呼び出しには長い時間がかかり、サーバーにとって致命的になります。スレッドがこのメソッドを呼び出し続けると、調整する方法がないためです。他のスレッドの場合、サーバーはブロックされます。アップグレードされたコードは次のようになります。
public class Single { priate static Single single = null; private Single() { } public Single getInstance() { if (single == null) { synchronized (Single.class) { single = new Single() } } return single; } }
注意して観察した結果、この方法ではロックが存在しないことがわかりました。2 つのスレッドが初めて getInstance() メソッドに到達すると、そのうちの 1 つが実行完了後にブロックされる必要があります。空かどうかを判断するには、この方法で複数のオブジェクトが生成され、その後アップグレードされます。結果のコードは次のとおりです。
public class Single { private static Single single = null; private Single() { } public Single getInstance() { if (single == null) { synchronized (Single.class) { if (single == null) { single = new Single (); } } 単一を返します。
こうすることで、上記の問題は発生せず、2回目にメソッドが実行されるときはif判定をスキップして直接シングルが返されるため、一度ロックされるだけで再度ロックされることはありません。となり、実行効率が非常に高くなります。
しかし、それでもまだ問題はあります。オブジェクトにメモリ内の値が最初に割り当てられるのか、オブジェクトが最初に作成されるのかがわからないため、jdk1 以降では 2 番目のプログラムが半分初期化されたオブジェクトを取得する可能性があります。この状況を回避するには、 volatile キーワードを使用できます。コードは次のとおりです。
public class Single { private static volatile Single single = null; private Single() { } public Single getInstance() { if (single == null) { synchronized (Single.class) { if (single == null) { single = newシングル(); } } 単一を返します。
でも、この状況はめったに使われません、私はただ学びに来ただけです、へへ。