Как обновить объект класса Singleton - PullRequest
0 голосов
/ 22 октября 2019

У меня есть одноэлементный класс, как показано ниже

class A{

private volatile static  A a;
//declaration of LinkedHashMap

private A(){
//lot of code that puts values in the map
}

public static A getInstance() {
        if (a== null) {
            synchronized (A.class) {
                if (a== null) {
                    a = new A();
                }
            }
        } 
        return a;
    }

}

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

1 Ответ

1 голос
/ 22 октября 2019

вам гораздо проще написать свой синглтон просто: 'private static A a = new A ();'- это ничего не стоит (это не вызывается, если кто-то не ссылается на A в своем коде, а затем он будет вызываться в тот момент времени), и устраняет проблемы с тем, как ваш фрагмент кода пытается (неправильно)попробуйте сделать синглтон.

Для обновления, ну просто .. напишите метод для этого. Не блокируйте общедоступные объекты (класс A.class адресуется всем кодом), это все равно, что иметь открытые поля. Сделайте закрытый объект, который вы заблокируете. Затем, есть метод с именем 'getMap', который синхронизируется с этой частной блокировкой, а также метод с именем 'refreshMap', который также делает это. Теперь любой код, который вызывает getMap, пока работает операция обновления, будет ждать, пока операция обновления не будет завершена, и затем вернет вновь созданную карту. Вызовите обновить себя, если карта пуста. Итак, что-то вроде:

public class A {
    private static final A INSTANCE = new A();
    private LinkedHashMap<Integer, String> map;
    private final Object locker = new Object();
    private A() {}

    public static A getInstance() {
        return INSTANCE; // Look how simple this got!
    }

    public Map<Integer, String> getMap() {
        synchronized (locker) {
            if (map == null) refresh();
            return map;
        }
    }

    public void refresh() {
        synchronized (locker) {
            // refresh map here...
            map = ....;
        }
    }
}
...