Latest web development tutorials

Singletonパターン

シングルトン(Singletonパターン)Javaは、最も単純なデザインパターンの一つです。 デザインパターンのこのタイプのオブジェクトを作成するための最良の方法を提供する、スキーマを作成属します。

このモデルは、単一のオブジェクトが作成されていることを保証しながら、独自のオブジェクトを作成するための責任がある単一のクラスが含まれます。 このクラスは、彼らの訪問のユニークなオブジェクトを提供し、それが直接アクセスすることができ、あなたはそのクラスのオブジェクトをインスタンス化する必要はありません。

注意:

  • 1、シングルトンクラスにはインスタンスが1つだけ持つことができます。
  • 2、シングルトンクラスは、独自のインスタンスを作成する必要があります。
  • 3、シングルトンクラスは、すべての他のオブジェクトにこの例を提供しなければなりません。

入門

意図:クラスの1つだけのインスタンスを確保し、それをアクセスするためのグローバルアクセスポイントを提供します。

主なソリューション:グローバルクラス頻繁に作成および破棄を使用しています。

使用するときは:あなたは、システムリソースを節約するためにすると、インスタンスの数を制御したいとき。

解決方法:それは返す場合、次に作成されていない場合、システムはすでに、この単一のケースを持っているかどうかを決定します。

キーコード:コンストラクタはプライベートです。

応用例:1は、当事者は、一つだけの大統領を持つことができます。それ同時に必然的に複数のプロセスまたはスレッド現象の文書、すべてのファイルの処理が一意のインスタンスによって実行されなければならないとき2、Windowsがファイルの操作で、マルチスレッド、マルチプロセスです。 図3に示すように、機器管理者の一部は、多くの場合、同じファイルを印刷することはできません2つのプリンタに対処するために必要な出力で2プリンタとコンピュータのような、単一ケースモデルとして設計されています。

利点:1は、1つのインスタンスのみのメモリで、(例えば、管理のホームページキャッシュの学校など)は、特に頻繁に作成および破棄のインスタンスをメモリのオーバーヘッドを削減します。図2に示すように、(例えば、ファイル書き込み操作のような)リソースの複数の占有を回避します。

短所:いいえインタフェースは、クラスがだけでなく、インスタンス化する方法などの外側に、内部ロジックを心配する必要があり、継承、および単一責任原則の競合ではありません。

使用シナリオ:1は、固有のシリアル番号の生成を必要とします。2、WEBカウンター、単一のケースで一度リガでなく、すべてのデータベースがキャッシュされたを更新します。 3、このようなデータベースなどへのI / O接続などのリソースの過剰消費の必要性によって作成されたオブジェクト。

注:のgetInstance()メソッドは複数回インスタンス化される原因インスタンスに複数のスレッドを防ぐために(Singleton.class)が同期ロック同期を使用する必要があります。

実現

我々はSingleObjectクラスを作成します。SingleObjectクラスは、独自のプライベートコンストラクタと静的インスタンスを持っています。

SingleObjectクラスは、静的インスタンスの外に取得するための静的メソッドを提供します。 SingletonPatternDemo、SingleObjectオブジェクトを取得しSingleObjectクラスを使用して、私たちのデモクラス。

SingletonパターンUMLダイアグラム

ステップ1

シングルトンクラスを作成します。

SingleObject.java

パブリッククラスSingleObject {

   //)(=新しいSingleObjectをプライベート静的SingleObjectインスタンスSingleObjectオブジェクトを作成します。

   クラスはプライベートSingleObjectをインスタンス化されませんので、//、コンストラクタを非公開にします(){}

   //公共利用可能な静的SingleObjectのgetInstance(){の唯一のオブジェクトを取得します。
      インスタンスを返します。
   }

   公共ボイドshowMessage(){
      System.out.println( "Hello Worldの!");
   }
}

ステップ2

シングルトンクラスから一意のオブジェクトを取得します。

SingletonPatternDemo.java

パブリッククラスSingletonPatternDemo {
   公共の静的な無効メイン(文字列[] args){

      //コンストラクタ//不正なコンパイル時エラー:コンストラクタSingleObject()が表示されていない// SingleObjectオブジェクト=新しいSingleObject();

      //オブジェクトのみ利用可能SingleObjectオブジェクトを取得= SingleObject.getInstance();

      //メッセージの表示object.showMessage();
   }
}

ステップ3

出力を確認します。

ハローワールド!

いくつかのSingletonパターンの実装

以下のように、シングルトンパターンをいくつかの方法を実装します。

1、怠惰なスタイル、スレッドセーフ

遅延初期化されている:はい

マルチスレッドセーフである:いいえ

簡単:難易度を達成

説明:このメソッドは、最大の問題は、マルチスレッドをサポートしていない、この実装を達成するための最も基本的な方法です。そこに同期しないロックがないので、厳密な意味では、それはシングルトンではありませんので。
このようにレイジーローディングは明らかにマルチスレッド動作しないでスレッドの安全性、作業を必要としません。

コード例:

パブリッククラスシングルトン{  
    プライベート静的シングルトンインスタンス。  
    プライベートシングルトン(){}  
  
    パブリック静的シングルトンのgetInstance(){  
    {(インスタンス== null)の場合  
        インスタンス=新しいシングルトン();  
    }  
    インスタンスを返します。  
    }  
}  

いくつかの実装の次のプレゼンテーションでは、複数のスレッドをサポートしていますが、性能が異なります。

2、怠惰なスタイル、スレッドセーフ

遅延初期化されている:はい

マルチスレッドセーフである:はい

簡単:難易度を達成

説明:このように、良好な遅延ロードを持っている、マルチスレッドでうまく動作することができます、しかし、例99%が同期を必要としない、非常に低い効率です。
利点:最初の呼び出しは無駄なメモリを回避するために、初期化されました。
短所:単一のケースを確実にするために同期ロックする必要がありますが、ロックが効率に影響を与えます。
getInstance()アプリケーションのパフォーマンスが(あまり頻繁に使用する)重要ではありません。

コード例:

パブリッククラスシングルトン{  
    プライベート静的シングルトンインスタンス。  
    プライベートシングルトン(){}  
    パブリック静的同期シングルトンのgetInstance(){  
    {(インスタンス== null)の場合  
        インスタンス=新しいシングルトン();  
    }  
    インスタンスを返します。  
    }  
} 

3、飢え式

遅延初期化されている:いいえ

マルチスレッドセーフである:はい

簡単:難易度を達成

説明:それはより一般的な、しかし、ごみのオブジェクトになりやすいのです。
長所:ロックされていない、効率が向上します。
短所:クラスローダが初期化され、メモリが無駄になります。
これは、classloderメカニズムに基づいている原因クラスは、さまざまな理由のをロードするが、それは、クラスローダをインスタンス化されるときに、Singletonパターンのほとんどは、getInstanceメソッドを呼び出すことですが、それは決定できないが、例えば、同期マルチスレッドを回避他の方法(または他の静的メソッド)は、クラスのロードにつながる。この時間は、明らかに、インスタンスの初期化レイジーローディング効果に達しなかったがあります。

コード例:

パブリッククラスシングルトン{  
    プライベート静的シングルトンのインスタンス=新しいシングルトン();  
    プライベートシングルトン(){}  
    パブリック静的シングルトンのgetInstance(){  
    インスタンスを返します。  
    }  
}  

4、ダブルチェックロック/ダブルチェックロック(DCL、それはダブルチェックロックです)

JDKのバージョン:JDK1.5から

遅延初期化されている:はい

マルチスレッドセーフである:はい

より複雑な:難しさを実現

説明:このメソッドは、ダブルロック機構、安全性を使用して、マルチスレッドの場合に高い性能を維持します。
アプリケーションののgetInstance()パフォーマンスが重要です。

コード例:

パブリッククラスシングルトン{  
    プライベート揮発性の静的なシングルトンシングルトン。  
    プライベートシングルトン(){}  
    パブリック静的シングルトンgetSingleton(){  
    {(シングルトン== null)の場合  
        同期(Singleton.class){  
        {(シングルトン== null)の場合  
            シングルトン=新しいシングルトン();  
        }  
        }  
    }  
    シングルトンを返します。  
    }  
}  

5、登録型/静的な内部クラス

遅延初期化されている:はい

マルチスレッドセーフである:はい

一般:難しさを実現

説明:このメソッドは、同じ効果のダブルチェックロックモードを実現することができますが、実装が容易になります。静的フィールドの遅延初期化を使用して、このような方法で使用されるの代わりに二重ロックモードを確認する必要があります。 これは、ダブルチェックロックモードは、インスタンスフィールドを初期化するために必要な遅延を使用することができ、静的フィールドの場合に適用されます。
このアプローチは、それが3異なる方法である、一つのスレッドだけのインスタンス初期化することを確実にするためにclassloderメカニズムを利用します:限りシングルトンクラスがロードされている第三の方法として、インスタンスがインスタンス化される(到達していない遅延ロード効果)が、この方法は、インスタンスが初期化されないことがあり、シングルトンクラスがロードされています。 SingletonHolderクラスがアクティブに使用されていないので、のみ、コールgetInstanceメソッドを使用して表示されたインスタンスをインスタンス化されるSingletonHolderクラスを、ロードされ表示されます。 想像してみて、あなたは、インスタンスのリソース集中型のインスタンスを作成すれば、それはロードを遅延したかったようであるように、他の一方で、それはシングルトンクラスを確保することはできませんので、あなたが、シングルトンクラスローダをインスタンス化したくない場合にも、他の分野で活躍することができますロードされ、この時間は、明らかに不適切なインスタンスを生成します。 この時間は、方法の最初の3種類と比較して、このような方法でそれは非常に合理的です。

コード例:

パブリッククラスシングルトン{  
    プライベート静的クラスSingletonHolder {  
    プライベート静的最後のシングルトンインスタンス=新しいシングルトン();  
    }  
    プライベートシングルトン(){}  
    公共の静的な最終的なシングルトンのgetInstance(){  
    SingletonHolder.INSTANCEを返します。  
    }  
}   

6、列挙

JDKのバージョン:JDK1.5から

遅延初期化されている:いいえ

マルチスレッドセーフである:はい

簡単:難易度を達成

説明:この実装はまだ広く採用されていないが、これはシングルトンパターンを実装するための最良の方法です。これは、絶対の複数のインスタンスを防止するための自動サポートのシリアル化メカニズムより簡潔です。
このアプローチは、Effective Javaプログラミング言語の作者ジョシュブロッホは、それがマルチスレッドの同期の問題を回避することができるだけでなくする方法を提唱しているが、また自動的にデシリアライゼーションは絶対に複数のインスタンス化を防ぐため、新しいオブジェクトを再作成して防止するために、シリアル化メカニズムをサポートしています。 だけ助けることが不思議に感じることができない、このように書き、JDK1.5の列挙型のプロパティの後に参加しましたので、実際には、ほとんど使用されません。
反射攻撃によってプライベートコンストラクタを呼び出すことはありません。

コード例:

パブリック列挙シングルトン{  
    INSTANCE;  
    公共ボイドwhateverMethod(){  
    }  
}  

経験則:通常の状況下では、第一種及び第二種怠惰な方法の使用はお勧めしません、第三の方法空腹男使用することをお勧めします。あなたが遅延ロードの効果は明ら​​かである実装する場合にのみ、我々は登録する方法の最初の5つの種類が使用されます。 それが作成するオブジェクトをデシリアライズするために来た場合は、第六列挙モードを使用して試すことができます。 あなたは他の特別なニーズをお持ちの場合は、第四の二重チェックをロックモードを使用して検討することができます。