public void testWeakKeys() throws Exception {
ConcurrentMap<Key, Value> map = new MapMaker()
.weakKeys() // 指定Map保存的Key為WeakReference機(jī)制
.makeMap();
Key key = new Key();
map.put(key, new Value()); // 加入元素
key = null; // key變成了WeakReference
System.gc();// 觸發(fā)垃圾回收
TimeUnit.SECONDS.sleep(1L);
assertTrue(map.isEmpty()); // map空了车胡,因?yàn)閃eakReference被回收
}
是不是夠簡(jiǎn)單?他不僅支持WeakKeys照瘾,還支持WeakValues匈棘。 Java代碼public void testWeakValues() throws Exception {
ConcurrentMap<Key, Value> map = new MapMaker()
.weakValues() // 指定Map保存的Value為WeakReference機(jī)制
.makeMap();
Key key = new Key();
Value value = new Value();
map.put(key, value); // 加入元素
key = null; // Key成了WeakReference
System.gc();// 觸發(fā)垃圾回收
TimeUnit.SECONDS.sleep(1L);
assertFalse(map.isEmpty()); // map里的東西還在,因?yàn)閂alue還是StrongReference
value = null; // 這次value也變成了WeakReference
System.gc(); // 觸發(fā)垃圾回收
TimeUnit.SECONDS.sleep(1L);
assertTrue(map.isEmpty()); // map真空了析命,因?yàn)閂alue是WeakReference被回收
}
還可以選用SoftKeys主卫,和SoftValues,隨意組合碳却,比只能WeakKey的WeakHashMap擴(kuò)展性強(qiáng)太多了队秩。 再來看看On-demand value computation笑旺,自定義構(gòu)建元素昼浦。想象下面的場(chǎng)景,你要為一個(gè)查詢學(xué)生信息的DAO增加結(jié)果緩存筒主,并且結(jié)果超過60秒過期关噪,我們可以用裝飾模式結(jié)合MapMaker簡(jiǎn)單的實(shí)現(xiàn)。 Java代碼interface StudentDao {
Information query(String name);
}
class StudentDaoImpl implements StudentDao {
// 真正去查數(shù)據(jù)庫的實(shí)現(xiàn)類 代碼省略
}
// 裝飾器
class CachedStudentDao implements StudentDao {
private final StudentDao studentDao;
private final ConcurrentMap<String, Information> cache;
public CachedStudentDao(final StudentDao studentDao) {
Preconditions.checkNotNull(studentDao, "studentDao");
this.studentDao = studentDao;
this.cache = new MapMaker() // 構(gòu)建一個(gè) computingMap
.expiration(60, TimeUnit.SECONDS) // 元素60秒過期
.makeComputingMap(new Function<String, Information>(){
@Override
public Information apply(String name) {
return studentDao.query(name);
}
});
// 傳入匿名Function自定義緩存的初始化乌妙。如果緩存中沒有name對(duì)應(yīng)的數(shù)據(jù)使兔,則調(diào)用真正的dao去數(shù)據(jù)庫查找數(shù)據(jù),同時(shí)緩存結(jié)果藤韵。
}
@Override
public Information query(String name) {
return cache.get(name); // 從computing cache中取結(jié)果
}
}
public void test() {
StudentDao cachedStudentDao = new CachedStudentDao(studentDaoImpl);
// 裝飾了studenDaoImpl的cachedStudentDao具備了緩存結(jié)果的能力虐沥。
}
線程安全,高并發(fā)性能泽艘,元素過期都實(shí)現(xiàn)了欲险,并且代碼很簡(jiǎn)潔。多虧了MapMaker匹涮,臟活天试、累活,就交給它啦然低。不過要注意的是喜每,要遵循ConcurrentHashMap的規(guī)范,其不允許有Null的Key和Value雳攘。如果查詢出來的結(jié)果可能為Null的带兜,可用簡(jiǎn)單的包裝類包裝一下,這里不給出代碼了吨灭。 怎么樣刚照?你是不是心動(dòng)了呢?快下載來看看吧沃于。