前些时候用到了apache的Lrumap,用来维护N个用户的定购关系列表,大致是Lrumap<string,List<string>>后来测试的时候出现了一个很奇怪的问题,就是系统运行一段时间后会发现某些用户的某些定购关系在内存中不存在,但是数据库中却是有值的。开始的时候我怀疑用户名id(即map的key)所对应的List空掉了,最后想了很久发现应该是值缺失了一部分,而不是空掉了。
下边是一个经过抽象后的简单模型:
下边是一个经过抽象后的简单模型:
Map<String, List<String>> m = new LruMap<String, List<String>>;
// 由于最新的apache 的common-collection3.2.1包中的lrumap是不同步的.
// 所以我想当然的对其进行了一次同步。
boolean foo(value) {
List<String> list;
synchronized (m) {
list = m.get(uid);
}
if (list == null) {
list = getdataFormDatabase(); // 将其放在外边是由于这块可能非常慢,而并发又很严重,考虑到性能就放同步块外边了
synchronized (m) {
m.put(uid, list);
}
return list.contains(value);
} else {
return list.contains(value); // 问题出现在这里,返回的是false,实际上应该为true
}
}
foo(uid, value) {
List<String> list;
synchronized (m) {
list = m.get(uid);
}
if (list == null) {
list = getDataFromDatabase(); // 理由同上
list.add(value);
synchronized (m) {
m.put(uid,list);
}
} else {
list.add(value);
}
}