スレッドセーフな遅延初期化を実現するための推奨されるアプローチは何ですか? 例えば、
// Not thread-safe
public Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
スレッドセーフな遅延初期化を実現するための推奨されるアプローチは何ですか? 例えば、
// Not thread-safe
public Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
シングルトンの場合、静的初期化のためにタスクを JVM コードに委任することによる洗練されたソリューションがあります。
public class Something {
private Something() {
}
private static class LazyHolder {
public static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
見る
http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
Crazy Bob Lee のこのブログ投稿
http://blog.crazybob.org/2007/01/lazy-loading-singletons.html
最も簡単な方法は、静的内部ホルダー クラスを使用することです。
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
}
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
これはダブルチェックと呼ばれます。これをチェックしてくださいhttp://jeremymanson.blogspot.com/2008/05/double-checked-locking.html
synchronized
適切なロックを使用してコードをブロックに入れます。他にも高度に専門的な手法がいくつかありますが、どうしても必要な場合以外は避けることをお勧めします。
static
また、インスタンス メソッドを示す傾向がある SHOUTY ケースを使用しました。本当に静的な場合は、決して変更できないことを確認することをお勧めします。静的な不変を作成するだけでコストがかかる場合、クラスのロードはとにかく怠惰です。別の (おそらくネストされた) クラスに移動して、作成を可能な限り最後の瞬間まで遅らせることができます。
あなたが達成しようとしているものに応じて:
すべてのスレッドで同じインスタンスを共有する場合は、メソッドを同期化できます。これで十分でしょう
スレッドごとに個別のインスタンスを作成する場合は、java.lang.ThreadLocal を使用する必要があります。
インスタンスを同期済みとして取得するメソッドを定義してみてください。
public synchronized Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
または変数を使用します。
private static final String LOCK = "LOCK";
public synchronized Foo getInstance(){
synchronized(LOCK){
if(INSTANCE == null){
INSTANCE = new Foo();
}
}
return INSTANCE;
}