2013-03-01 31 views
11

E.g我Singleton類靜態字段instance與幾個不同的類加載器Singleton類

public class Singleton { 

    private static Singleton instance; 

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

我可以用兩個不同的類加載器加載兩次此類。我怎麼能避免它?這是不安全和危險的。

此外,如果我將實例設置爲null,它是否會將這兩個類設置爲null?

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

如果您確實想要實現單例設計模式,請在Java中使用[枚舉類型](http://en.wikipedia.org/wiki/Singleton_pattern#The_Enum_way) - 「*單元素枚舉類型是實現單例模式的最佳方式*「 – Lion 2013-03-01 11:46:47

+7

枚舉模式不會阻止每個類加載器存在一個實例,對嗎? – keuleJ 2013-03-01 11:49:03

+0

關於單身人士:http://weblogs.java.net/blog/kirillcool/archive/2005/08/how_single_is_y.html – keuleJ 2013-03-01 12:05:21

回答

24

如果要在類加載器真正的Singleton,那麼你需要一個共同的父加載有問題的類,或者你需要自己指定的類加載器。

更新:從@Pshemo的評論下面的博客內容的公平比特可能直接來自JavaWorld Article。我已經離開了博客條目,因爲它可能仍然有助於某人,但它值得知道內容最初來自哪裏。

原文: 有一個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

好的答案!如果你在這裏包含了一個解決方案的代碼示例,那將會更好,因爲它能夠鏈接到鏈接的文章。 – 2013-03-01 13:21:26

+0

請包括代碼示例。 – bsiamionau 2013-03-01 13:30:02

+0

按要求提供的代碼片段:-) – 2013-03-01 13:45:29

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()

Properties是基於Hashtable的,所以它是線程安全的(根據文檔)。所以可以使用props.computeIfAbsent()。但我更喜歡這種方式。

這裏還可以閱讀:Scope of the Java System Properties

我只是寫它,有機會的話有什麼東西我忽略會阻止這樣做。

+0

有一個錯誤在那裏......修復 – 2017-11-22 23:59:15