【问题标题】:ExpiringMap or TTL based Cache基于 ExpiringMap 或 TTL 的缓存
【发布时间】:2015-03-13 17:15:42
【问题描述】:

http://www.java2s.com/Code/Java/Collections-Data-Structure/ExpiringMap.htm

Q1) 我在看上面的缓存代码。我很困惑为什么在调用 getLastAccessTime 时我们需要一个锁。该方法仅由 Expirer 线程调用。

Q2) 假设,如果 Map 仅由线程调用,那么我们是否需要 ExpiringObject 中的可重入锁。因为调用Map的put方法时setLastAccessTime只有线程调用,而Expirer线程调用getLastAccessTime方法。 我问的原因是,我测试插入 1M 个对象,可重入锁占用超过 100MB

【问题讨论】:

    标签: java caching collections locks lru


    【解决方案1】:

    需要锁,因为 long 值不能在 32 位系统上自动更新。

    替代方案:

    • 将 long 替换为 Long。引用更新是原子的。

    • 使用 AtomicLong

    • 继续使用 Lock 对象,但使用大小约为可用 CPU 的两倍的锁的静态数组,并使用 locks[hashCode() % locks.length]

    • 对其进行索引

    最后一个选项:使用缓存,它已经以优化的方式执行此操作,例如 EHCache、Google Guava 或 cache2k。

    【讨论】:

    • 是的,我决定使用 EhCache,但我还是想知道解决方案。您的所有建议都非常出色。
    【解决方案2】:

    要回答您的问题,我不确定为什么 lastAccessTimeLock 需要锁定,因为对其的更改不需要与其他任何内容的更改(原子地)同时发生。 IMO,它不需要锁。不过,您需要确保其他线程可以看到对 lastAccessTimeLock 的更改,这可以通过将其标记为 volatile 或使用 AtomicLong 来完成。

    至于您的内存使用问题,您可以查看这个ExpiringMap 库而不是使用 Mina 实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      • 2010-10-01
      相关资源
      最近更新 更多