2016-04-01 2 views
-1

マルチスレッド環境でクラスのインスタンスを1つだけ作成するには、以下の構造を持つシングルトンクラスを作成します。より良いパフォーマンスのためにJavaでシングルトンデザインパターンでNullチェックを乗り越える方法

class Singleton { 

    private volatile static Singleton _instance; 

    private Singleton() { 
     // preventing Singleton object instantiation from outside 
    } 

    public static Singleton getInstanceDC() { 
     if (_instance == null) { 
      synchronized (Singleton.class) { 
       if (_instance == null) { 
        _instance = new Singleton(); 
       } 
      } 
     } 
     return _instance; 
    } 
} 

しかし、我々は、すべてのスレッドがnull checkをしながら、静的な関数からオブジェクトを取得する前に支払わなければならないペナルティの乗り心地を取得することによって、クラスのパフォーマンスを向上させることができる方法はありますか?

+7

ヌルチェックは本当に安いです。これは、たとえ最適化が可能であっても、最適化について心配するものではありません。疑問です。特に、CPUがほとんど常に同じ方法をとるチェックが最適化されている場合、CPUは非常に魅力的です。これは基本的に無料で、あなたは心配することを_really _見つけなければなりません。 –

+0

最初のアクセス時に '_instance'を作成するのではなく、静的に初期化できませんか?そうすれば、各アクセスでnullをチェックする必要はありません。 –

+0

有効なJavaの第2版を参照 – AlexWien

答えて

3

これは早すぎる最適化と呼ばれます。あなたは実際には nullチェックが問題を引き起こしている知っている(それは私を信じていない)。ヌルチェックのコストはナノ秒のオーダーです。

実際に実際の問題があることを確認した後でのみ、パフォーマンスが心配です。次に、問題の原因となっているコードのセクションを特定するためにいくつかのプロファイリングを行い、その認識をバックアップするためのパフォーマンス統計なしで問題と思われるものを最適化しないでください。

+0

ありがとう@ジム私はそれがパフォーマンスを打つことはない同じことを知っている。これは非常にシニアな開発者のインタビューで尋ねられた質問の1つでしたが、私はそれに対処できませんでした。 – Arpan

2

Josh Blochによると、 Java 1.5以降で有効なJava Second Editionは、これが最善のアプローチです。

public enum Singelton { 
    INSTANCE; 
} 

洗練されたシリアライゼーションやリフレクション攻撃に対しても安全です。

しかし、常にシングルトンはテスト可能性を守っていることに注意してください。 あなたの質問のシングルトンは、リフレクションを使ってテスト目的でリセットすることができますが、私の答えにあるものはおそらくできません。

シングルトンが必要かどうかを2回考えることをお勧めします。私はいつもシングルトンを避けます。

0

シングルトンの最善のアプローチは、リソース制約の理由がない限り早期にインスタンス化することです。

public class Singleton 
{ 
    //guaranteed thread safe 
    private static final Singleton _instance = new Singleton(); 

    public static Singlegon getInstance() 
    { 
     return _instance; 
    } 
} 
関連する問題