具有多个不同类装入器的单例类

2022-09-02 12:31:46

例如,我有带有静态字段的类:Singletoninstance

public class Singleton {

    private static Singleton instance;

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

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

另外,如果将实例设置为 null,是否会将两个类都设置为 null?

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

答案 1

如果您希望跨类装入器为 true,那么您需要一个公共父级来装入有问题的类,或者您需要自己指定类装入器。Singleton

更新:从下面@Pshemo的评论来看,下面博客中的相当多的内容可能直接来自JavaWorld文章。我已经留下了博客条目,因为它可能仍然可以帮助某人,但值得知道内容最初来自哪里。

源语言:有一个博客条目可以给你一种方法来做到这一点“(尽管我还没有尝试过!),它看起来相当合理

根据下面的要求,我上面的链接中的代码片段 - 我建议您访问博客,但要了解完整的上下文:

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

答案 2

这是一个黑客滥用事实,扩展,一个旧的不幸的设计决策。PropertiesMap

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是基于 -的,所以它是线程安全的(根据文档)。因此,可以使用.但我更喜欢这种方式。Hashtableprops.computeIfAbsent()

另请阅读此处:Java 系统属性的范围

我刚刚写了它,有可能有一些我忽略了的东西会阻止它工作。


推荐