問題点および改善策
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/06/11 16:01 UTC 版)
「Singleton パターン」の記事における「問題点および改善策」の解説
Java における一般的な Singleton パターンの記述は上述した通りであるが、この方法は同期化コストが高い。そこでdouble-checked lockingというイディオムが考えられたが、「アウトオブオーダー書き込み」を許すJavaプラットフォームのメモリーモデルが原因で、同期化に失敗する(言うまでもないが、この最適化による副作用は Java だけのものではない)。この問題を克服しようとするとコードが肥大化しコストがかかる。そこで現在では以下のように static フィールドを用いることが推奨されている。 final class Singleton { private static final Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return Singleton.instance; }} これによりコストは改善される。同期化は行われないが、static フィールドの初期化はそのクラスが呼び出される最初の一回しか行われないため、何回getInstance()メソッドを呼んでもスレッドアンセーフを心配する必要はなくなるだけでなく、コストパフォーマンスも非常に高い。 ただしこの場合、Singletonクラスがロードされたときに初期化されるのであって、getInstance()が初めて呼ばれたときではない。このことはプログラマの意図しないタイミングで初期化が始まってしまい混乱の元となる場合がある。そこで en:Initialization-on-demand holder idiom と呼ばれる手法、すなわちinstanceフィールドのみを別のホルダークラスに隔離して、そのホルダークラスがロードされたときにSingletonの初期化が行なわれるよう改善したものが下記である。 final class Singleton { private Singleton() {} private static class SingletonHolder { private static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; }} これでSingletonクラスがロードされたときではなく、getInstance()呼び出しによりSingletonHolderクラスがロードされたときにSingletonクラスが初期化される。
※この「問題点および改善策」の解説は、「Singleton パターン」の解説の一部です。
「問題点および改善策」を含む「Singleton パターン」の記事については、「Singleton パターン」の概要を参照ください。
- 問題点および改善策のページへのリンク