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
答案 0 :(得分:0)
需要锁定,因为长值无法在32位系统上以原子方式更新。
备选方案:
用long替换long。参考更新是原子的。
使用AtomicLong
继续使用Lock对象,但使用大小约为可用CPU双倍数的锁的静态数组,并使用锁索引[hashCode()%locks.length]
最后一个选项:使用缓存,它已经以优化的方式执行此操作,如EHCache,Google Guava或cache2k。
答案 1 :(得分:0)
要回答你的问题,我不确定为什么lastAccessTimeLock
需要锁定,因为对它的更改不需要与其他任何内容(原子地)的更改重合。 IMO,它不需要锁定。您可能希望确保其他线程可以看到对lastAccessTimeLock
的更改,这可以通过将其标记为volatile
或使用AtomicLong
来实现。
至于您的内存使用问题,您可以查看此ExpiringMap库,而不是使用Mina实现。