ExpiringMap或基于TTL的缓存

时间:2015-03-13 17:15:42

标签: java caching collections locks lru

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

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

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

2 个答案:

答案 0 :(得分:0)

需要锁定,因为长值无法在32位系统上以原子方式更新。

备选方案:

  • 用long替换long。参考更新是原子的。

  • 使用AtomicLong

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

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

答案 1 :(得分:0)

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

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