В нашем веб-приложении существуют классы «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 не поддерживается