2012-12-05 9 views
9

私は2つのオプションがありますか? (シングルスレッドまたはマルチスレッド)シングルトンとのpublic static変数Javaの

アップデート:私はBill Pughまたはenumメソッドを認識しています。 私は正しい方法を探しているわけではありませんが、私は1を使用しました。実際には1または2の違いはありますか?

+0

更新された質問の後に違いはありません。 –

+1

この質問はシングルトンとは関係ありません。同期/非同期コンテキストから静的フィールドにアクセスするかどうか尋ねます。タグを編集してください。 – Juvanis

+0

@BhavikAmbani私は、最初のオプションはインスタンスを取得しようとする各スレッドをロックするので、ややパフォーマンスが低下するため、私は同意しません。 –

答えて

10

主な違いは、最初のオプションでは、getInstanceが呼び出されたときにのみシングルトンが初期化されますが、2番目のオプションでは、そのクラスがロードされるとすぐに初期化されます。

怠惰である第三の(好ましい)オプションとスレッドセーフ列挙を使用することである。

public enum Singleton { 
    INSTANCE; 
} 
+0

私の間違いは、何とかそれを逃した。今質問を更新しました。また、私はENUMシングルトンインスタンスを認識していますが、違いを知りたかっただけですが、とにかく感謝しています。 – Achow

2

一つの違いがあります:

溶液1を遅延初期化では、シングルトンインスタンスになります熱心な初期化がgetInstance

溶液2の最初の呼び出しである作成、シングルトンインスタンスが作成されるときにクラスloades

これらの2つのスレッドはどちらも安全です.2番目のスレッドをマルチスレッドで呼び出すと少し誤解を招きます。

+1

まあ、私はマルチスレッドbit.Itに入れてdidnt編集されました..:P – Achow

1

したがって、上記の両方のオプションはスレッドセーフです。しかし、​​オプションでは、instanceを呼び出すスレッドごとにこのロックを取得する必要があり、これにより多くの処理が行われるとパフォーマンスが低下します。また、メソッドレベルで​​を使用すると、公に利用可能なロック(クラスそのもの)を使用する潜在的な問題があります。したがって、あるスレッドがこのロックを取得すると、デッドロックで終了する可能性があります。 static finalオプションはパフォーマンスは向上しますが、シングルトンの遅延初期化は実行されません(システムによっては問題になることはありません)。以下のようにシングルトンの初期化スレッドセーフで怠惰なことができます

別のオプションは次のとおりです。

public class MySingleton{ 
     private static class Builder{ 
      private static final MySingleton instance = new MySingleton(); 
     } 

     public static MySingleton instance(){ 
      return Builder.intance; 
     } 
} 

含むクラスのどのメソッドが実行される前に、静的な内部クラスが初期化されるようにguarenteedされるので、これは動作します。

+0

-1投票者、推論を明確にするために気をつけますか? –

+0

私はちょうど答えを読んで、それは私が思った問題を持っていません。申し訳ありませんが試合。 :)私の-1を削除しました。答えは私には言葉サラダのように見えますが...実際の違い(怠け者と熱心な初期設定)にはほとんど触れていません。あなたはパフォーマンスとロックについて言及しますが、それは主な違いではありません。 – cHao

-1

Javaでのシングルトン実装(本当に必要な場合)は、賢明な初期化と遅延初期化の両方について説明したよりも洗練された方法で実行できます。 Joshua Blochによって記載されたthe enum wayおよびBill Pughによって提案されたthe SingletonHolder solutionをそれぞれチェックする。

ウィキペディアの記事はパターンを理解するための良いスタートでもあり、あなたの質問に答えてくれます。

+1

質問に答えません。あなたがより良い方法を提案したいなら、それは問題ありません...しかし、あなたがそうしている間に少なくとも質問に答えてください。 – cHao

+0

ええ、あなたはそうです... –

2

第1の解決策はレイジーであるように見えるが、実際はそうではない。

クラスは、最初に静的メソッド/フィールドにアクセスしたときに初期化されます。

このクラスの公開アクセス可能な静的メソッド/フィールドは、getInstance()である可能性があります。それがシングルトンのポイントです。

次に、誰かが初めてgetInstance()を呼び出すと、クラスが初期化されます。つまり、2つのソリューションは、基本的に怠惰で同じです。

もちろん、第2のソリューションはよりよく見え、より優れたパフォーマンスを示します。

+0

怠け者で、getInstance()が明示的に呼び出されるまで、シングルトンのインスタンスは作成されません。クラスは明らかに両方の時間ロードされます。または私は何かを逃していますか?第2の解決策の – Achow

+1

では、インスタンスはクラスの初期化時にのみ作成されます。静的メソッド/フィールドがアクセスされたとき、すなわちgetInstance()が呼び出されたときにのみ、クラスが初期化される。 – irreputable

関連する問題