为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

红颜莎娜 2019-10-30 11:08:41
例如我有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;
查看完整描述

3 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

如果您希望Singleton跨类加载器为true ,则需要一个公共父级来加载所讨论的类,或者您需要自己指定类加载器。


更新:来自@Pshemo的评论下面的博客中相当一部分内容可能直接来自JavaWorld Article。我保留了博客条目,因为它可能仍然可以帮助某人,但是值得知道该内容最初来自何处。


原文: 有一个博客条目为您提供了一种执行此操作的方法”(尽管我还没有尝试过!),而且看起来相当合理


按照下面的要求,我在上面的链接中提供了一个代码段-我建议您尽管访问全文,但还是请访问该博客:


private static Class getClass(String classname) throws ClassNotFoundException {

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

    if(classLoader == null) 

        classLoader = Singleton.class.getClassLoader();

      return (classLoader.loadClass(classname));

}


查看完整回答
反对 回复 2019-10-30
?
aluckdog

TA贡献1847条经验 获得超7个赞

这是一个滥用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系统属性的范围


我只是写了它,有可能我忽略了某些东西,这会阻止它工作。


查看完整回答
反对 回复 2019-10-30
?
函数式编程

TA贡献1807条经验 获得超9个赞

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

查看完整回答
反对 回复 2019-10-30
  • 3 回答
  • 0 关注
  • 456 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信