2015-03-13 244 views
0

http://www.java2s.com/Code/Java/Collections-Data-Structure/ExpiringMap.htmExpiringMap或基于TTL的高速缓存

Q1)我在看上面的高速缓存代码。我很困惑getLastAccessTime被调用时为什么需要锁。该方法仅由Expirer线程调用。 Q2)假设,如果Map仅由线程调用,那么我们是否需要在ExpiringObject中有一个可重入锁。因为setLastAccessTime在调用Map的put方法时仅由线程调用,并且由Expirer线程调用getLastAccessTime方法。 我问的原因是,我测试了插入1M个对象,Reentrant Lock需要超过100MB

回答

0

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

替代方案:

  • 更换长由长。参考更新是自动的。

  • 使用的AtomicLong

  • 继续使用锁定对象,但使用锁的静态阵列的大小有关可用CPU的双号和索引它与锁[hashCode()方法%locks.length]

而最后一个选项:使用一个缓存,这是一个优化的方式,如EHCache,Google Guava或cache2k。

+0

是的,我决定使用EhCache,但我想知道解决方案。你所有的建议都非常出色。 – Paul 2015-03-13 20:16:40

0

要回答你的问题,我不确定为什么lastAccessTimeLock需要锁定,因为对它的更改不需要与任何其他操作(原子)的更改一致。海事组织,它不需要锁。您需要确保lastAccessTimeLock的更改可以被其他线程看到,可以通过将其标记为volatile或使用AtomicLong来完成。

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