Синхронизация в экземпляре Java Class <T>для хранения и извлечения динамически созданных прокси-классов во время выполнения - PullRequest
0 голосов
/ 22 января 2019

В нашем веб-приложении существуют классы «Access Bean» с некоторыми методами, которые выполняют запросы к БД, они вызываются несколько раз за запрос. Поэтому их необходимо кэшировать, но исходные классы нельзя изменить, поскольку они взяты из используемой нами среды, поэтому для обхода этого я создал фабрику, которая создает прокси-класс для переноса и кэширования вызовов методов для исходных существующих методов bean-компонентов. Я хочу сохранить прокси-класс в ConcurrentHashMap<Class, Class> (где ключ - это исходный класс, а значение - в новом прокси-классе), чтобы при необходимости его можно было быстро найти в других потоках.

Я хочу, чтобы он был быстрым и с очень низким уровнем конкуренции, поэтому мне нужно синхронизироваться с объектом класса EJB, переданным в качестве параметра метода для двойной проверки блокировки, чтобы получить прокси-класс из карты или управлять доступом к фабрике прокси если класс прокси отсутствует.

Map<Class, Class> classProxyMap = ConcurrentHashMap<Class, Class>;

@SuppressWarnings("unchecked")
private static <P extends B> Class<P> getProxyClass(Class<B> beanClass) {

Class<P> proxyClass = classProxyMap.get(beanClass);

    if (proxyClass == null) {
        synchronized (beanClass) {
            proxyClass = classProxyMap.get(beanClass);
            if (proxyClass == null) {
                proxyClass = proxyFactory.makeProxyClass(beanClass, false);
                classProxyMap.put(beanClass, proxyClass);
            }
        }
    }

    return (Class<P>) proxyClass;
}

Кажется, что это не работает в среде QA, хотя я не совсем уверен, что это (синхронизация) является проблемой. Поэтому я хочу знать, можно ли синхронизировать таким образом или нужно просто синхронизировать карту и покончить с этим.

[EDIT] Сервер приложений - это Java 7, поэтому ConcurrentHashMap.computeIfAbsent не поддерживается

1 Ответ

0 голосов
/ 22 января 2019

Зачем вам нужна дополнительная синхронизация, если у вас уже есть ConcurrentHashMap?

Почему бы не использовать существующий ConcurrentHashMap # computeIfAbsent?

Map<Class, Class> classProxyMap = ConcurrentHashMap<Class, Class>;

@SuppressWarnings("unchecked")
private static <P extends B> Class<P> getProxyClass(Class<B> beanClass) 
{
    return classProxyMap.computeIfAbsent(
            beanClass, 
            (clazz) -> proxyFactory.makeProxyClass(clazz, false));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...