シングルトン(Singletonパターン)は、Javaのデザインパターンの最も簡単なの一つです。デザインパターンのこのタイプは、所属するスキーマを作成するオブジェクトを作成するための最良の方法を提供し、。このモデルは、単一のオブジェクトが作成されていることを保証しながら、独自のオブジェクトを作成するための責任がある単一のクラスが含まれます。このクラスは、直接アクセスできるオブジェクト、オブジェクトクラスのインスタンスにアクセスするための唯一の方法を提供します。
シングルトン5種類作成しました:
- タイプ飢え:クラスの初期化時に、オブジェクトは、すぐに本質的にスレッドセーフな、高いコールの効率をロードします。
- レイジースタイル:クラスが初期化されると、実際に遅延読み込み機能を持つオブジェクトを作成するために行く時間を使用する必要はありませんオブジェクトを初期化します。
- 静的な内部クラスの仕方:漢それぞれの利点の怠惰と空腹スタイルの組み合わせは、オブジェクトがロードされます真のニーズは、負荷クラスはスレッドセーフです。
- シングルトン列挙:列挙シングルトンパターン、単純な、高効率のコールを達成する、列挙自体が単一の場合であり、反射を介して、JVMによって基本的な保護を提供し、脆弱性のデシリアライゼーションを回避するため、不利には、遅延ローディングがないことです。
- デュアル検出モード: (JVM 自体並べ替えのために初期化されてもよい回以上現れます)。
次のようにコードは次のとおりです。
// 空腹中国風 パブリック クラスSingletonDemo01 { // クラスが初期化されると、オブジェクトがすぐにロードされ、スレッド本質的に安全、高効率を呼び出し プライベート 静的を SingletonDemo01 singletonDemo01 = 新新SingletonDemo01(); プライベートSingletonDemo01(){ System.out.printlnは( " SingletonDemo01初期化" ); } パブリック 静的のgetInstance(){SingletonDemo01 のSystem.out.println( "のgetInstance " ); 戻りsingletonDemo01を; } パブリック 静的 ボイドメイン(文字列[]引数){ SingletonDemo01 S1 =SingletonDemo01.getInstance(); SingletonDemo01 S2 = SingletonDemo01.getInstance()。 System.out.println(S1 == S2)。// 结果为トゥーレ } }
// 怠惰なスタイル パブリック クラスSingletonDemo02 { // クラスが初期化され、使用する実際の必要性が権利を作成する際に、オブジェクトは、初期化されていません。 プライベート 静的SingletonDemo02 singletonDemo02、 プライベートSingletonDemo02(){ } パブリック 同期 静的SingletonDemo02のgetInstance(){ IF(singletonDemo02 == NULL ){ singletonDemo02 = 新しい新しいSingletonDemo02(); } 戻りsingletonDemo02を; } パブリック 静的 ボイドメイン(文字列[]引数){ S1 SingletonDemo02 =SingletonDemo02.getInstance(); SingletonDemo02 S2 = SingletonDemo02.getInstance()。 System.out.println(S1 == S2)。// 结果为真 } }
// 静的内部クラスの実施形態 パブリック クラスSingletonDemo03 { プライベートSingletonDemo03(){ System.out.printlnは( "初期化.." ); } パブリック 静的 クラスSingletonClassInstance { プライベート 静的 最終 SingletonDemo03 singletonDemo03 = 新しい新しいSingletonDemo03(); } // 方法はありません同期 パブリック 静的のgetInstance(){SingletonDemo03 のSystem.out.println( "のgetInstanceが" ;) を返すSingletonClassInstance.singletonDemo03を; } 公共 静的 ボイドメイン(文字列[]引数){ SingletonDemo03 S1 = SingletonDemo03.getInstance(); SingletonDemo03 S2 = SingletonDemo03.getInstance(); System.out.printlnは(S1 == S2); // 結果が真である } }
//利点:アカウントに怠惰なメモリ最適化モード(初期設定を使用して)、安全性飢えモード(反射しない侵略を)取ります。
//短所:オブジェクトは静的な内部クラスを作成しませんが、そのクラスのオブジェクトがまだ作成され、オブジェクトは永続的なバンドの一部ではあるが、これを行う必要がある2つのクラス。
// 枚举单例式 パブリック クラスユーザー{ パブリック 静的ユーザーのgetInstance(){ 戻り)(SingletonDemo04.INSTANCE.getInstanceします。 } プライベート 静的 列挙SingletonDemo04 { INSTANCE。 // 枚举元素为单例 プライベートユーザーユーザー。 プライベートSingletonDemo04(){ System.out.printlnは( "SingletonDemo04" )。 ユーザー = 新しいユーザー(); } パブリックユーザのgetInstance(){ 戻りユーザ。 } } パブリック 静的 ボイドメイン(文字列[]引数){ ユーザU1 = User.getInstance()。 ユーザU2 = User.getInstance()。 System.out.println(U1 == U2)。// 结果为真 } }
// 双重检测方式 パブリック クラスSingletonDemo04 { プライベートSingletonDemo04 singletonDemo04。 プライベートSingletonDemo04(){ } 公共SingletonDemo04のgetInstance(){ 場合(singletonDemo04 == NULL ){ 同期(本){ 場合(singletonDemo04 == NULL ){ singletonDemo04 = 新しいSingletonDemo04()。 } } } 戻りsingletonDemo04。 } }
利点:
- シングルモードの実施例、実施形態の単一の実施例で得られたすべてのクラスのシングルトンインスタンスの活性は、同じインスタンスです。これは、すべてのオブジェクトのインスタンスへのアクセス権を持っていることを確認するために、自分自身でインスタンス化さ他のオブジェクトを防ぎます。
- 一定の可撓性を有するシングルトンパターンは、それらのクラスが変化する過程で対応するインスタンスの伸縮性に基づいて制御プロセスをインスタンス化します。
- それが唯一のインスタンスへのアクセス制御を提供します。
- オブジェクトが作成され、破棄されたときに、システムリソースを節約することができるように、1つのオブジェクトのみが頻繁にシングルトンパターンは、システムメモリ内にありますので、確かに、システムのパフォーマンスを向上させることができます。
- これは、インスタンスの数が可変することができます。
- 共有リソースの複数の割り当てを避けてください。
短所:
- オブジェクトの同じタイプは、常にシーンチェンジと異なる実施形態で発生していない場合は、件名を変更するには、単一の場合は、誤ったデータが別の状態で保存することができない原因になります。
- これシングルトンクラスを拡張し、単一モデルの抽象化レイヤ興味がないので、大きな困難を持っています。
- ある程度「単機能の原則」に反する重すぎる責任シングルトンクラス、。
- 虐待のシングルケースがあまりにも多くのオブジェクトの接続プール接続プールのオーバーフローの共有プログラム発生につながる可能性があり、そのようなシングルトンクラスのデザインなど、データベース接続プールオブジェクトなどのリソースを節約するために、いくつかの否定的な問題をもたらすでしょう。長い時間のためのオブジェクトをインスタンス化した場合使用されていない、システムは、オブジェクトの状態が失われる、ごみを収集することができると考えられます。
注意事項:
- シングルトンは、それ以外の場合は、新しいオブジェクトをインスタンス化します、反射モードを使用して作成することができません。
- 怠惰なシングルトンを使用した場合、スレッド安全性の問題に注意してください。
- シングルトンと怠惰なシングルトンコンストラクタは、シングルモードの場合も継承することができ、プライベートなので、継承することができない(例えば、モードレジスタベース)。
シナリオ:
Singletonパターンは、このようにメモリを節約、オブジェクトを作成することができますが、オブジェクトが公共の使用のための機会にする必要があり、オブジェクトのアクセス速度を高速化。
- データ・ソースを使用して同じオブジェクトに接続された複数のモジュール。
- 頻繁にインスタンス化にオブジェクトを必要とし、その後破棄。
- あなたがオブジェクトを作成する時間がかかりすぎるか、あまりにも多くのリソースを消費しますが、頻繁にオブジェクトを使用していました。
- ステートフルなツールは、オブジェクト。
- オブジェクトデータベースや、頻繁にアクセスされるファイル。
- リソース共有の場合は、原因リソースの演算結果に、パフォーマンスなどの損失を避けるために。このようなログファイル、アプリケーション設定など。
- 制御リソース場合は、リソース間の相互通信を容易にします。スレッドプールのような。
例えば:
- 外部の資源:各コンピュータがプリンタの数を持っていますが、一つだけPrinterSpooler、プリンタに同時に出力を2つの印刷ジョブを避けるために。
- 内部资源:大多数软件都有一个(或多个)属性文件存放系统配置,这样的系统应该有一个对象管理这些属性文件。
- Windows的TaskManager(任务管理器)就是典型的单例模式,想想看,你能同时打开两个windows task manager吗?
- windows的Recycle Bin(回收站)也是典型的单例模式。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
- 网站的计数器,一般也是采用单例模式实现,否则难以同步。
- 应用程序的日志应用,一般都是使用单例模式实现,因为共享的日志文件一直处于打开状态,因此只能有一个实例去操作,否则不方便追加内容。
- Web应用的配置对象的读取,一般也应用单例模式,因为配置文件是共享的资源。
- 数据库连接池的设计一般是采用单例模式,因为数据库连接是一种数据库资源。数据库软件系统中使用数据库连接池,主要是节省打开或者关闭数据库连接所引起的效率损耗,这种效率上的损耗还是非常昂贵的,使用单例模式来维护,可以大大降低这种损耗。
- 多线程的线程池的设计一般也是采用单例模式,因为线程池要方便对池中的线程进行控制。
- 操作系统的文件系统,也是单例模式实现的具体例子,一个操作系统只能有一个文件系统。