Java シングルトンと静的 - 実際のパフォーマンス上の利点はありますか?

StackOverflow https://stackoverflow.com/questions/28241

  •  09-06-2019
  •  | 
  •  

質問

CVS ブランチをマージしていますが、大きな変更の 1 つは、シングルトン パターンが発生する場所を、静的初期化ブロックとすべての静的メソッドを持つ抽象クラスに置き換えることです。

多くの競合をマージする必要があるため、これは保持する価値がありますか? このリファクタリングが価値があると判断されるのはどのような状況ですか?

このアプリは Weblogic 8.1 (つまり JDK 1.4.2) で実行しています。


ごめんなさい、トーマス、はっきりさせてください。

HEAD バージョンには従来のシングルトン パターン (プライベート コンストラクター、getInstance() など) があります。

ブランチ バージョンにはコンストラクターがなく、「パブリック抽象クラス」であり、オブジェクトのすべてのメソッドが「静的」になるように変更されました。プライベート コンストラクターに存在していたコードは、静的ブロックに移動されます。

その後、クラスのすべての使用法が変更され、マージ時に複数の競合が発生します。

この変更が行われたケースはいくつかあります。

役に立ちましたか?

解決

厳密な実行時のパフォーマンスの観点から見ると、その違いはごくわずかです。2 つの主な違いは、「静的」ライフサイクルがクラスローダーにリンクされているのに対し、シングルトンの場合は通常のインスタンスのライフサイクルであるという事実にあります。通常、ClassLoader ビジネスから離れたほうが、特に Web アプリケーションをリロードしようとするときに、いくつかの厄介な問題を避けることができます。

他のヒント

状態を保存する必要がある場合はシングルトンを使用し、それ以外の場合は静的クラスを使用します。何かを保存する必要がない限り、たとえ単一のインスタンスであっても、何かをインスタンス化することに意味はありません。

静的メソッドとフィールドはサブクラスによって拡張またはオーバーライドできないため、静的は拡張性に悪影響を及ぼします。

単体テストにも悪影響を及ぼします。単体テスト内では、クラスローダーを制御できないため、さまざまなテストの副作用が波及するのを防ぐことはできません。ある単体テストで初期化された静的フィールドが別の単体テストでも表示されたり、さらに悪いことに、テストを同時に実行すると予測できない結果が生じたりします。

シングルトンは、控えめに使用すれば通常は問題ないパターンです。私は DI フレームワークを使用し、それに代わってインスタンスを管理させることを好みます (おそらく、Guice のように異なるスコープ内で)。

私の元の投稿が正しい理解であり、リンクされている Sun の議論が正確である場合 (おそらくそうであると思います)、明確さとパフォーマンスの間でトレードオフを行う必要があると思います。

次の質問を自分自身に問いかけてください。

  1. Singleton オブジェクトを使用すると、私がやっていることはより明確になりますか?
  2. このタスクを実行するにはオブジェクトが必要ですか、それとも静的メソッドの方が適していますか?
  3. シングルトンを使用しないことで得られるパフォーマンスは必要ですか?

私の経験から言えば、重要なのは単体​​テストでどちらが模擬しやすいかということだけです。シングルトンはモックアウトするのが簡単で自然だといつも感じていました。組織が JMockit の使用を許可している場合は、これらの懸念を克服できるため、問題ありません。

この議論は役に立ちますか?(別のプログラミング フォーラムにリンクすることがタブーかどうかはわかりませんが、議論全体をそのまま引用するのは避けたい =) )

このテーマに関する日のディスカッション

技術的には静的メソッドの方が効率的ですが、ほとんどの場合、問題になるほどの違いは生じないという評決が下されているようです。

パフォーマンスを測定するためのコードを作成します。答えは、JVM (Sun の JDK は JRockit とは異なる動作をする可能性があります) とアプリケーションが使用する VM フラグによって異なります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top