具有多个不同类加载器的Singleton类

例如我有Singleton静态字段的类instance:


public class Singleton {


    private static Singleton instance;


    // other code, construct, getters, no matter    

}

我可以使用两个不同的类加载器两次加载该类。我该如何避免呢?这是不安全和危险的。


另外,如果我将instance设置为null,那么是否将两个类的instance都设置为null?


Singleton singleton = Singleton.getInstance();

singleton = null;



慕标琳琳
浏览 232回答 2
2回答

慕无忌1623718

如果您希望Singleton跨类加载器为true ,则需要一个公共父级来加载所讨论的类,或者您需要自己指定类加载器。private static Class getClass(String classname) throws ClassNotFoundException {    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();    if(classLoader == null)         classLoader = Singleton.class.getClassLoader();      return (classLoader.loadClass(classname));}

绝地无双

这是一个滥用Properties扩展事实的技巧,这是一个Map旧的不幸的设计决定。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()。但是我更喜欢这种方式。另请阅读:Java系统属性的范围我只是写了它,有可能我忽略了某些东西,这会阻止它工作。

呼啦一阵风

您确定Sneha是该帖子的作者(或至少部分关于类加载器)吗?从我所看到的链接文章已经发布,8 JANUARY 2009但是它看起来与javaworld出版的相当老文章的一部分相同Apr 25, 2003。博客上的文章甚至包含句子“ 可以使用前面的方法代替Class.forName() ”,这似乎没有上下文,因为Class.forName()在更早的地方没有使用任何方法,而在Javaworld中是有意义的,因为示例10使用了反射。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java