2013-03-01 10 views
11

例えば私は、静的フィールドinstanceを持つクラスSingleton持っている:私は2つの異なるクラスローダで二回、このクラスをロードすることができますシングルトンクラス

public class Singleton { 

    private static Singleton instance; 

    // other code, construct, getters, no matter  
} 

を。どうすればそれを避けることができますか?それは危険で危険です。

また、instanceをnullに設定すると、両方のクラスでnullに設定されますか?

Singleton singleton = Singleton.getInstance(); 
singleton = null; 
+2

シングルトンのデザインパターンを実現したい場合は、Javaの[enum type](http://en.wikipedia.org/wiki/Singleton_pattern#The_Enum_way)に従ってください - "*単一要素の列挙型は、シングルトン* " – Lion

+7

を実装する最良の方法は、クラスローダーごとに1つのインスタンスの存在を妨げることはありませんか? – keuleJ

+0

シングルトンについて:http://weblogs.java.net/blog/kirillcool/archive/2005/08/how_single_is_y.html – keuleJ

答えて

24

あなたはクラスローダに当てはまりSingletonをしたい場合は、問題のクラスをロードするために共通の親を必要とするか、クラスローダを自分で指定する必要があります。

更新:下記の@Pshemoからのコメントから、以下のブログの内容のかなりの部分がJavaWorld Articleから直接来るかもしれません。私はまだ誰かを助けるかもしれないとしてブログのエントリを残しましたが、コンテンツが元々どこから来たのか知る価値があります。

オリジナル: はあなたに(!私はそれを試してみましたhaventはないが)「これを行う方法を提供しますblogエントリーがあり、そしてそれはかなり合理的に見える

からのコードスニペットここの下に要求されたように私上記のリンク - 私はあなたが完全なコンテキストにかかわらず、ブログを訪問をお勧めします:

private static Class getClass(String classname) throws ClassNotFoundException { 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
    if(classLoader == null) 
     classLoader = Singleton.class.getClassLoader(); 
     return (classLoader.loadClass(classname)); 
} 
+1

ニースの答え!リンクされた記事にクレジットを付けて、ソリューションのコード例をここに含めればさらに良いでしょう。 –

+0

コード例を含めてください。 – bsiamionau

+0

要求通りにコードスニペット:-) –

0

これはPropertiesは、古い不幸な設計上の決定をMapを拡張しているという事実を悪用ハックです

012。
public final class JvmWideSingleton 
{ 
    private static final JvmWideSingleton INSTANCE; 

    static { 
     // There should be just one system class loader object in the whole JVM. 
     synchronized(ClassLoader.getSystemClassLoader()) { 
      Properties sysProps = System.getProperties(); 
      // The key is a String, because the .class object would be different across classloaders. 
      JvmWideSingleton singleton = (JvmWideSingleton) sysProps.get(JvmWideSingleton.class.getName()); 

      // Some other class loader loaded JvmWideSingleton earlier. 
      if (singleton != null) { 
       INSTANCE = singleton; 
      } 
      else { 
       // Otherwise this classloader is the first one, let's create a singleton. 
       // Make sure not to do any locking within this. 
       INSTANCE = new JvmWideSingleton(); 
       System.getProperties().put(JvmWideSingleton.class.getName(), INSTANCE); 
      } 
     } 
    } 

    public static JvmWideSingleton getSingleton() { 
     return INSTANCE; 
    } 
} 

これはパラメータ化できますが、初期化は遅延してgetSingleton()になります。

PropertiesHashtableです。したがって、ドキュメントごとにスレッドセーフです。したがって、props.computeIfAbsent()を使用することができます。しかし、私はそれがもっと好きです。

また、ここで読む:Scope of the Java System Properties

を、私はちょうどそれを書いたと私はそれが働いてからこれを妨げる見落とし何かがあるのチャンスがあります。

+0

そこに1つのバグ –

関連する問題