У меня есть веб-служба, которая имеет ~ 1k запросы потоков, работающих одновременно в среднем. Эти потоки обращаются к данным из кеша (в настоящее время на ehcache). Когда записи в кеше истекают, поток, который попадает в истеченную запись, пытается получить новое значение из БД, тогда как другие потоки также пытаются попасть в этот блок ввода, т. Е. Я использую декоратор BlockingEhCache. Вместо того, чтобы другие потоки ожидали «выборки потока», я хотел бы, чтобы другие потоки использовали значение «stale», соответствующее «пропущенному» ключу. Есть ли какие-либо сторонние разработчики ehcache для этой цели? Знаете ли вы о других решениях кэширования, которые имеют такое поведение? Другие предложения?Java многопоточное кэширование с одним обновлением Thread
ответ
Я не знаю, что EHCache достаточно для того, чтобы дать конкретные рекомендации для решения вашей проблемы, поэтому я опишу, что бы я сделал, без EHCache.
Предположим, что все потоки обращаются к этому кешу, используя интерфейс службы, называемый FooService, и сервисный компонент, называемый SimpleFooService. Служба будет иметь методы, необходимые для получения необходимых данных (которые также кэшируются). Таким образом, вы скрываете тот факт, что он кэшируется из внешнего интерфейса (объекты HTTP-запросов).
Вместо простого хранения данных, которые будут кэшироваться в свойстве службы, мы создадим для него специальный объект. Назовем его FooCacheManager. Он будет хранить кеш в свойстве в FooCacheManger (скажем, его типа Map). У него есть получатели, чтобы получить кеш. Он также будет иметь специальный метод reload(), который будет загружать данные из БД (путем вызова методов службы для получения данных или через DAO) и заменить содержимое кеша (сохраненного в свойстве) ,
Хитрость здесь заключается в следующем:
- Объявите свойство кэша в FooCacheManger в AtomicReference (новый объект, объявленный в Java 1.5). Это гарантирует безопасность потока при чтении и назначении. Ваши действия чтения/записи никогда не сталкиваются или не читают полузаписанное значение.
- Перезагрузка() сначала загрузит данные во временную карту, а затем, когда она будет завершена, она назначит новую карту для свойства, сохраненного в FooCacheManager. Поскольку свойство AtomicReference, присвоение является атомарным, поэтому оно в основном позволяет мгновенно отображать карту без необходимости блокировки.
- TTL-реализация - Имейте FooCacheManager реализовать интерфейс QuartzJob и эффективно выполнять кварцевое задание. В методе выполнения задания запустите перезагрузку(). В Spring XML задайте это задание для запуска каждые xx минут (TTL), которые также могут быть определены в файле свойств, если вы используете PropertyPlaceHolderConfigurer.
Этот метод эффективен, так как для чтения нитей:
- Не блокировать для чтения
- Не называется isExpired() на каждом чтения, который является 1k/сек.
Также при записи данных поток записи не блокируется.
Если это неясно, я могу добавить пример кода.
Поскольку ehcache удаляет устаревшие данные, другой подход может быть для обновления данных с вероятностью, которая увеличивается по мере приближения времени истечения срока действия и равна 0, если время истечения достаточно «далеко».
Итак, если для потока 1 нужен некоторый элемент данных, он может обновить его, хотя данные еще не старые. Тем временем нить 2 нуждается в тех же данных, это может использовать существующие данные (пока обновленная нить еще не закончена). Возможно, поток 2 может попытаться сделать обновление.
Если вы работаете со ссылками (поток обновления загружает объект, а затем просто меняет ссылку в кеше), то для получения и установки операций в кеше не требуется отдельная синхронизация.
- 1. Повсеместное многопоточное поведение (Java)
- 2. Java многопоточное программирование
- 3. Java Single Thread Использование ЦП и многопоточное использование ЦП
- 4. Java Многопоточное добавление векторов
- 5. Многопоточное приложение на Java?
- 6. Websphere hung thread - с обновлением MQ
- 7. Java-создание прокси-сокета многопоточное
- 8. Многопоточное умножение матриц в Java
- 9. Java-код гонки состояние многопоточное?
- 10. Обновление строки с одним обновлением datagridview
- 11. Многопоточное разворачивание на Java
- 12. java многопоточное обновление ajax
- 13. JAVA потребительский производитель многопоточное приложение - поток кода
- 14. Многопоточное поведение?
- 15. Многопоточное обновление Oracle в Java
- 16. Вопрос с Java thread
- 17. Многопоточное приложение Java в кластере?
- 18. Многопоточное приложение с gtkD
- 19. Многопоточное суммирование с использованием события
- 20. Проблемы с новым обновлением java
- 21. проблема с обновлением java swing
- 22. Java JTable с частым обновлением?
- 23. Проблемы с обновлением jtable java
- 24. python запускает многопоточное многопоточное автоматическое
- 25. Java Многопоточное приложение использует только один Core
- 26. Условное планирование задач - многопоточное приложение Java
- 27. Многопоточное тестирование
- 28. java array thread-safety
- 29. Многопоточное возвращаемое значение
- 30. Скорость многих отдельных обновлений по сравнению с одним большим обновлением
Что происходит с записями в кеше, когда они истекают? Удаляются ли они из кеша или просто помечены? – mlschechter
Хорошая идея. Если элемент отмечен как истек, значение возвращается, а затем инициируется обновление. –
Еще одна возможность загрузки абсолютно нового и неиспользуемого кеша, а затем поменять его на старый кеш. –