我有一个具有约1k个请求线程的平均同时运行的Web服务。这些线程从缓存中访问数据(当前在ehcache上)。当缓存中的条目到期时,命中过期条目的线程尝试从数据库获取新值,而其他线程也试图访问该入口块,即我使用BlockingEhCache装饰器。我不希望其他线程在“获取线程”上等待,我希望其他线程使用与“未命中”键相对应的“陈旧”值。有没有第三方为此目的开发ehcache装饰器?你知道有这种行为的其他缓存解决方案吗?其他建议?具有单个更新程序线程的Java多线程缓存
4
A
回答
1
我不知道EHCache足够好给出具体的建议来解决您的问题,所以我会概述我会做什么,没有EHCache。
我们假设所有线程都使用名为FooService的Service接口和名为SimpleFooService的服务bean访问此缓存。该服务将具有获取所需数据(也被缓存)所需的方法。这样你就隐藏了它从前端缓存的事实(http请求对象)。
不是简单地将要缓存的数据存储在服务中的某个属性中,而是为它创建一个特殊对象。我们称之为FooCacheManager。它会将缓存存储在FooCacheManger中的一个属性中(比方说它的类型为Map)。它会让getters获得缓存。它还会有一个名为reload()的特殊方法,它将从数据库加载数据(通过调用服务方法来获取数据或通过DAO),并替换缓存的内容(保存在属性中) 。
的伎俩在这里是如下:
- 声明缓存财产FooCacheManger为AtomicReference(Java 1.5中的新申报对象)。这可以确保在读取并分配给它时的线程安全。您的读/写操作永远不会发生冲突,或者读取半写值。
- reload()将首先将数据加载到一个临时映射中,然后当它完成时它会将新映射分配给保存在FooCacheManager中的属性。由于该属性是AtomicReference,因此该赋值是原子的,因此它基本上是在不需要锁定的情况下瞬间刷新地图。
- TTL实现 - 让FooCacheManager实现QuartzJob接口,并使其实际成为石英工作。在作业的执行方法中,让它运行reload()。在Spring XML中,定义这个作业是为了每运行xx分钟(你的TTL),如果你使用PropertyPlaceHolderConfigurer,它也可以在属性文件中定义。
这种方法是有效的,因为读出线程:
- 不要阻塞用于读
- 不要称为isExpired()上的每个读出,这是1K /秒。
此外,写入线程在写入数据时不会阻塞。
如果不清楚,我可以添加示例代码。
0
由于ehcache删除陈旧的数据,不同的方法可能是刷新数据的概率随着过期时间的增加而增加,如果过期时间“足够”远,则为0。
所以,如果线程1需要一些数据元素,它可能会刷新它,即使数据还不旧。 与此同时,线程2需要相同的数据,它使用现有数据(虽然刷新线程尚未完成),但它可能会使用现有数据可能。线程2可能会尝试刷新。
如果您正在使用引用(updater线程加载对象,然后简单地更改高速缓存中的引用),那么对高速缓存执行get和set操作不需要单独的同步。
相关问题
- 1. 具有缓存线程的单线程执行程序
- 2. 具有多线程的Java单进程
- 3. java编程和java单线程多线程问题(单线程与多线程)
- 4. java多线程ajax更新
- 5. java中有多线程的多线程
- 6. 更新从多个线程
- 7. 超时高速缓存线程池的单个线程
- 8. Java线程(多线程)
- 9. Java多线程 - 更少的线程或更少的线程做更多的线程?
- 10. 单线程C多线程#
- 11. 多线程vs单线程
- 12. 关于多线程的java多线程
- 13. 调用存储线程内的程序更新多条记录
- 14. java多线程应用程序更新数据库
- 15. 多线程:如何让jframe更新一个线程的日志?
- 16. Java线程程序
- 17. 的Java多线程的线程随机
- 18. 用线程更新JFrame? - Java
- 19. Java简单线程和单线程IllegalMonitorStateException
- 20. Java多线程
- 21. Java线程:运行一个简单的java线程程序输出混淆
- 22. 具有多个GUI线程的mdi应用程序
- 23. Java的多线程,让线程并行
- 24. Java中的多线程应用程序?
- 25. java中的多线程程序帮助
- 26. 在我的场景中,单个Java线程比多线程更好吗?
- 27. java线程简单的愚蠢程序
- 28. 多线程程序
- 29. C#,多线程 - 表单不更新
- 30. Android多线程UI更新
当缓存中的条目到期时会发生什么?他们是从缓存中删除,还是只是标记? – mlschechter 2010-09-30 01:24:14
好主意。如果元素被标记为过期,则返回该值,然后启动刷新。 – 2010-09-30 02:09:54
加载全新且未使用的缓存的另一种选择,然后将其与旧缓存交换。 – 2010-09-30 02:10:44