Подтвердить что ты не робот

Одиночный класс с несколькими различными загрузчиками классов

Например, у меня есть класс Singleton со статическим полем instance:

public class Singleton {

    private static Singleton instance;

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

Я могу загрузить этот класс дважды с помощью двух разных загрузчиков классов. Как я мог избежать этого? Это опасно и опасно.

Кроме того, если я установил экземпляр в значение null, будет ли он установлен равным null для обоих классов?

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

Ответ 1

Если вы хотите использовать true Singleton для загрузчиков классов, вам нужен общий родительский объект для загрузки рассматриваемого класса или вам нужно указать загрузчик классов самостоятельно.

Обновление: Из комментария от @Pshemo ниже справедливой части содержимого в блоге ниже может быть получена непосредственно из статьи JavaWorld., Я оставил запись в блоге, так как он все равно может помочь кому-то, но его стоит знать, откуда изначально вышло содержание.

Оригинал: Есть запись 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));
}

Ответ 2

Это хак, неправильно использующий тот факт, что 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 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

Я только что написал это, и есть шанс, что я упустил из виду, что помешало бы этому работать.