Используйте хорошо протестированное решение, такое как
new MapMaker().weakKeys().makeMap();
из Гуава . Вы даже можете делать такие вещи, как
new MapMaker().weakKeys()
.concurrencyLevel(16)
.expireAfterAccess(5, TimeUnit.MINUTES)
.maximumSize(1000)
.makeComputingMap(new Function<Class<?>, ServiceClass>() {
@Override
public ServiceClass apply(Class<?> myClass) {
return new ServiceClass(myClass);
}
});
, которая должна решить всю вашу проблему и предлагает множество возможностей для настройки кэширования.
Причиной тупика является блокировка записи, когда оба потока удерживают блокировку чтения. В отличие от понижения блокировки, обновление может блокировать. Сначала нужно снять блокировку чтения.
Когда вы получаете блокировку записи, вы должны проверить, не выполнял ли другой поток эту работу.