3

Mongodbで奇妙なエラーが発生しています。Mongodbでは、Mongoシングルトンを維持することになっています。これが実際に有効であることを確認したかっただけです。

public class DBManager {
    public static Mongo mongoSingleton = null;

    public static synchronized void getMongo(){
         if(mongoSingleton == null){
              mongoSingleton = new Mongo();
         }
         return mongoSingleton;
    }
}

ありがとう!

4

9 に答える 9

6

パブリックメンバーmongoSingletonをプライベートとして設定し、デフォルトのコンストラクターを非表示にする必要があります

それで

private static Mongo mongoSingleton = null;

private Mongo() {

}

クラスMongoの実装

public class Mongo {
    private static volatile Mongo instance;
    private Mongo() {
        ...
    }

    public static Mongo getInstance() {
        if (instance == null) {
            synchronized (Mongo.class) {
                if (instance == null) { // yes double check
                    instance = new Mongo();
                }
            }
        }

        return instance;
    }
}

利用方法

Mongo.getInstance();
于 2012-05-23T23:31:20.437 に答える
5

これは典型的なシングルトンパターンですが、Javaで推奨される方法は列挙型を作成することです。

public enum DBManager {
    INSTANCE;

    // implementation here
}

次に、次の方法でインスタンスを参照できます。

DBManager.INSTANCE

どちらの場合(列挙型またはシングルトンパターン)でも、結果はJVMごとではなく、ClassLoaderごとに1つのインスタンスになることに注意してください。

于 2012-05-23T23:36:58.110 に答える
1

いいえ、静的メンバーへのパブリックアクセスは、任意のインスタンスに変更できるためです。

もっと正気は次のようになります

public class DBManager {
    private static Mongo mongoSingleton = new Mongo();

    public static Mongo getMongo(){
       return mongoSingleton;
    }
}
于 2012-05-23T23:27:44.820 に答える
1
 public static Mongo mongoSingleton = null;

する必要があります

 private static Mongo mongoSingleton = null;

それ以外はよさそうだ。

于 2012-05-23T23:28:23.870 に答える
1

レイジー初期化を控える場合、これを行う最も安価な方法は、オブジェクトの作成時にシングルトンを作成することです。

public final class DBManager {
    private static final Mongo mongoSingleton = new Mongo();

    private DBManager() {}

    public static Mongo getMongo() {
         return mongoSingleton;
    }
}

このようにして、このメソッドのすべての呼び出しに存在する不要な同期オーバーヘッドを回避できます。Mongo自体がスレッドセーフである限り、getMongo()メソッドもスレッドセーフです。

ここでシングルトンに関するSun開発者の記事を読んでください。

于 2012-05-23T23:31:59.767 に答える
1

private static final Mongo mongo = new Mongo()、またはを使用するだけpublic static final Mongo mongo = new Mongo()です。それはより単純で潜在的に高速です。

于 2012-05-23T23:32:53.167 に答える
1

シングルトンの遅延初期化は過大評価されており、通常は必要なく、適切よりも多くの問題を引き起こします。synchronized同期(時間のかかる操作)が毎回実行されるため、静的ゲッター全体を作成するための単純なアプローチは良くありません。

ダブルチェックロックや初期化オンデマンドホルダーなど、より優れたアプローチがいくつかありますが、最も単純で通常は最良のアプローチは、JoshBlochの列挙型アプローチです。単一の要素で作成するenumと、防弾シングルトンが得られます。

public enum Mongo {

    INSTANCE;

    // instance fields, methods etc. as in any other class
}

privateこれは、コンストラクターとインスタンスを備えたクラスとほぼ機能的に同等ですが、より簡潔な構文と、リフレクションデシリアライズpublic static finalを介しても他のインスタンスを作成できないことを揺るぎなく保証するいくつかの優れた内部機能を備えています。

このアプローチは必ずしも熱心ではないことに注意してください。シングルINSTANCEは、クラスがJVMにロードされた直後に作成さMongoれます。これは、プログラムの開始直後にはハッピングされません。実際には、クラスが最初に参照されたときに発生します。この場合、staticフィールドまたはメソッドにアクセスします。

そして、それ以外に静的フィールドがなくINSTANCE、静的メソッドがない場合、これは実際に最初にINSTANCEアクセスされた後に発生します。

Mongo mongo = Mongo.INSTANCE;

言い換えれば、明示的な同期の問題がなく、実際には怠惰です。

于 2012-05-23T23:52:39.897 に答える
0

はい。ただし、メンバー変数を公開する必要はありません。ユーザーは同期ゲッター経由でアクセスする必要があります

于 2012-05-23T23:29:00.963 に答える
0

詳細を確認したい場合は、ステップバイステップで-このリンクをたどることができます-http : //www.javabeginner.com/learn-java/java-singleton-design-pattern

以下はそれを正しく行う方法の一例です。

public class DBManager {
private static Mongo mongoSingleton = null;

public static synchronized void getMongo(){
     if(mongoSingleton == null){
          mongoSingleton = new Mongo();
     }
     return mongoSingleton;
}

}

于 2012-05-23T23:32:01.103 に答える