Java設計モードの一例

3314 ワード

1.一例パターン紹介
単一のモードは、システム内のクラスが1つのインスタンスのみを生成することを保証するオブジェクト作成モードです.JAvaにおける一例モードの議論の範囲はJVMである.単例モードの利点は、1頻繁に使用されるオブジェクトに対して、オブジェクトの作成にかかる時間を省略することができ、これはそれらの重量級オブジェクトにとって非常に大きなシステムオーバーヘッドである.②new操作の回数が減少するため、システムメモリの使用頻度も低下し、GC圧力が軽減され、GC停止時間が短くなる.
2.単例の多様な書き方とそれぞれの特徴
1.餓漢モードpublic class HungurySingleton { private static final HungurySingleton mInstance = new HungurySingleton(); private HungurySingleton(){ System.out.println("create"); } public static HungurySingleton getInstance(){ return mInstance; } public static void printHello(){ System.out.println("Hello"); } public static void main(String[] args) { HungurySingleton.printHello(); } }上のコードは餓漢モードの一例であり、この書き方の特徴は、HungurySingletonというクラスがJVMにロードされると、一例オブジェクトが作成されることである.そのため、この書き方には先天的な不足があり、instanceインスタンスを遅延ロードすることができず、上のコードを実行すると発見される.HungurySingletonのクラスメソッドを呼び出しただけなのに、HungurySingletonインスタンスは作成されました.
2.怠け者モードpublic class LazySingleton { private static LazySingleton mInstance; private LazySingleton(){} public static LazySingleton getInstance(){ if (mInstance == null) mInstance = new LazySingleton(); return mInstance; } }上のコードは単一の例の怠け者モードであり、致命的な欠陥があり、マルチスレッド環境では単一の例を保証することができないため、スレッドの安全な怠け者モードがあります.public class LazySingleton { private static LazySingleton mInstance; private LazySingleton(){} public static synchronized LazySingleton getInstance(){ if (mInstance == null) mInstance = new LazySingleton(); return mInstance; } public static LazySingleton getInstance2(){ synchronized (LazySingleton.class){ if (mInstance == null) mInstance = new LazySingleton(); return mInstance; } } }は主にsynchronizedキーワードを使用しており、方法を修飾したり、コードブロックを使用したりすることができますが、性能効率が低いという欠点があります.
3.DCL(ダブルチェックロック機構)public class DclSingleton { private static volatile DclSingleton mInstance; private DclSingleton(){} public static DclSingleton getInstance(){ if (mInstance == null){ synchronized (DclSingleton.class){ if (mInstance == null) mInstance = new DclSingleton(); } } return mInstance; } } DCL単例モードは怠け者モードの最適化であり、コード中のインスタンスはvolatileによって修飾される.これは、volatileキーワードを使用しないと、JVMのインスタントコンパイラにおける命令再ソート最適化がコード実行に影響を与える可能性があるため、コードエラーを発生させ、単例効果を達成できないため、volatileが解決方法である.volatileの使用については後で検討します.
4.静的内部クラス書き方public class StaticInnerSingleton { private StaticInnerSingleton(){} public static StaticInnerSingleton getInstance(){ return SingletonHolder.mInstance; } private static class SingletonHolder{ private static final StaticInnerSingleton mInstance = new StaticInnerSingleton(); } }静的内部類の書き方はDCLの書き方に対するより近い一歩の最適化であり、実際のプロジェクトで使用することを提案し、その書き方は簡単明瞭で、スレッドは安全で、効率が高く、同時に遅延負荷を満たすことができる.この書き方は主にJVMの同期制御を用いており,同期制御とは何か,staticとfinalの2つのキーワードの使用である.staticは一意性を保証し、finalは可変性を保証する.これにより、JVM内のこのインスタンスで唯一かつ変更不可能であることを保証し、同時にスレッドが安全であり、synchronizedキーワードを使用せず、効率が高い.
5.列挙の書き方public enum EnumSingleton { INSTANCE; public void doSomething(){} }これが列挙単例の書き方で、本当に簡単です.列挙はjava 1ですから.5以降になりますので、この書き方は1.5以降のバージョンで使用できます.簡単なコードは1つのスレッドの安全を実現して、lazy loadingの単例、書き方の鬼斧神工というより、enumの3つの特性を適切に応用して、自由にシーケンス化して、スレッドの安全、単例を保証します.
6.まとめ
餓漢モード:instanceインスタンスに対して遅延ロードを行うことができない怠け者モード:マルチスレッドで一意性スレッドの安全を保証できない怠け者モード:synchronizedを使用して性能DCLモードに影響する:JVMのインスタントコンパイラの命令再ソート要因の影響を受け、volatileを使用して静的内部クラス/列挙モードを解くことができる:遅延ロード/スレッド安全/効率保証プロジェクトで静的内部クラスと列挙を使用して、単一の例を実装することを推奨します.