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

我应该使用哪个Java集合来实现线程安全缓存?

发布时间:2020-12-14 05:49:01 所属栏目:Java 来源:网络整理
导读:我希望实现一个简单的缓存,而不用做太多的工作(自然).在我看来,标准 Java集合之一应该是足够的,有一点额外的工作.具体来说,我正在存储来自服务器的响应,密钥可以是请求URL字符串或从URL生成的哈希码. 我原来以为我可以使用WeakHashMap,但是看起来这个方法强
我希望实现一个简单的缓存,而不用做太多的工作(自然).在我看来,标准 Java集合之一应该是足够的,有一点额外的工作.具体来说,我正在存储来自服务器的响应,密钥可以是请求URL字符串或从URL生成的哈希码.

我原来以为我可以使用WeakHashMap,但是看起来这个方法强制我来管理我想要保留的对象,任何没有强大引用的对象都被立即扫除.我应该尝试一个SoftReference值的ConcurrentHashMap吗?还是会那么清醒的呢?

我正在查看LinkedHashMap类.通过一些修改,它对MRU缓存看起来很有前途.任何其他建议?

无论我使用哪个集合,我应该尝试手动修剪LRU值,还是可以信任虚拟机偏倚回收最近访问的对象?

FYI,我正在Android开发,所以我不想导入任何第三方库.我正在处理一个非常小的堆(16到24 MB),所以VM可能非常渴望回收资源.我认为GC将是积极的.

解决方法

如果您使用基于SoftReference的键,VM将偏向(强烈)对最近访问的对象.然而,确定缓存语义将是相当困难的 – SoftReference为您提供的唯一保证(通过WeakReference)是在抛出OutOfMemoryError之前清除它.对于JVM实现来说,将它们与WeakReferences相同地对待它们将是完全合法的,此时可能会导致不缓存任何东西的缓存.

我不知道在Android上如何工作,但是随着Sun最近的JVM,可以使用-XX:SoftRefLRUPolicyMSPerMB命令行选项来调整SoftReference行为,该选项决定了可轻松访问的对象将保留的毫秒数,每MB的堆可用内存.正如你所看到的,这将非常难以获得任何可预测的生命周期行为,这种设置对于虚拟机中的所有软参考来说都是全局的,不能单独调整为单个类的使用SoftReferences(每次使用都会想要不同的参数).

制作LRU缓存的最简单方法是通过扩展LinkedHashMap as described here.由于您需要线程安全性,所以最初扩展的最简单的方法是在此自定义类的实例上使用Collections.synchronizedMap以确保安全并发行为.

提防过早优化 – 除非您需要非常高的吞吐量,否则粗略同步的理论上次优的开销不太可能是一个问题.而且这个好消息 – 如果分析表明由于强烈的锁定争用,您的运行速度太慢,您将有足够的信息可用于您的缓存的运行时使用,您可以提出一个合适的无锁替代方案基于ConcurrentHashMap与一些手动LRU处理),而不必猜测其负载配置文件.

(编辑:李大同)

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

    推荐文章
      热点阅读