加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

使用单个更新程序线程的Java多线程缓存

发布时间:2020-12-15 02:21:53 所属栏目:Java 来源:网络整理
导读:我有一个Web服务,平均有~1k个请求线程同时运行.这些线程从缓存(当前在ehcache上)访问数据.当缓存中的条目到期时,命中过期条目的线程尝试从DB获取新值,而其他线程也尝试命中此条目块,即我使用BlockingEhCache装饰器.我希望其他线程使用与“遗漏”键对应的“陈
我有一个Web服务,平均有~1k个请求线程同时运行.这些线程从缓存(当前在ehcache上)访问数据.当缓存中的条目到期时,命中过期条目的线程尝试从DB获取新值,而其他线程也尝试命中此条目块,即我使用BlockingEhCache装饰器.我希望其他线程使用与“遗漏”键对应的“陈旧”值,而不是让其他线程等待“获取线程”.是否有任何第三方为此目的开发了ehcache装饰器?您知道有任何其他具有此行为的缓存解决方案吗?其他建议?

解决方法

我不知道EHCache是??否足以提供解决问题的具体建议,所以我将概述我会做什么,没有EHCache.

假设所有线程都使用名为FooService的Service接口和名为SimpleFooService的服务bean访问此缓存.该服务将具有获取所需数据所需的方法(也被缓存).这样你就可以隐藏它从前端缓存的事实(http请求对象).

我们不是简单地将要缓存的数据存储在服务的属性中,而是为它创建一个特殊对象.我们称之为FooCacheManager.它会将缓存存储在FooCacheManger的一个属性中(比如它的Map类型).它将有getter来获取缓存.它还有一个名为reload()的特殊方法,它将从DB加载数据(通过调用服务方法来获取数据,或通过DAO),并替换缓存的内容(保存在属性中) .

这里的诀窍如下:

>将FooCacheManger中的缓存属性声明为AtomicReference(在Java 1.5中声明的新对象).这可以在您阅读并分配线程时保证线程安全.您的读/写操作永远不会发生冲突,或读取半写值.
> reload()将首先将数据加载到临时映射中,然后在完成后将新映射分配给保存在FooCacheManager中的属性.由于属性是AtomicReference,因此赋值是原子的,因此它基本上是在瞬间刷地图而不需要锁定.
> TTL实现 – 让FooCacheManager实现QuartzJob接口,并使其成为一个石英作业.在作业的execute方法中,让它运行reload().在Spring XML中,定义此作业每隔xx分钟运行一次(您的TTL),如果使用PropertyPlaceHolderConfigurer,也可以在属性文件中定义.

这个方法有效,因为阅读线程:

>不要阻止阅读
>不要在每次读取时调用isExpired(),即1k /秒.

写入线程在写入数据时也不会阻塞.

如果不清楚,我可以添加示例代码.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读