我正在爲用戶的照片實現一個LRU緩存,使用Commons Collections LRUMap(基本上是一個帶有小修改的LinkedHashMap)。 findPhoto方法可以在幾秒鐘內調用幾百次。緩存映射的這種用法在多線程環境中是否安全?
public class CacheHandler {
private static final int MAX_ENTRIES = 1000;
private static Map<Long, Photo> photoCache = Collections.synchronizedMap(new LRUMap(MAX_ENTRIES));
public static Map<Long, Photo> getPhotoCache() {
return photoCache;
}
}
用法:
public Photo findPhoto(Long userId){
User user = userDAO.find(userId);
if (user != null) {
Map<Long, Photo> cache = CacheHandler.getPhotoCache();
Photo photo = cache.get(userId);
if(photo == null){
if (user.isFromAD()) {
try {
photo = LDAPService.getInstance().getPhoto(user.getLogin());
} catch (LDAPSearchException e) {
throw new EJBException(e);
}
} else {
log.debug("Fetching photo from DB for external user: " + user.getLogin());
UserFile file = userDAO.findUserFile(user.getPhotoId());
if (file != null) {
photo = new Photo(file.getFilename(), "image/png", file.getFileData());
}
}
cache.put(userId, photo);
}else{
log.debug("Fetching photo from cache, user: " + user.getLogin());
}
return photo;
}else{
return null;
}
}
如你我不使用同步塊見。我假設這裏最壞的情況是一個競爭條件,導致兩個線程爲相同的userId運行cache.put(userId,photo)。但是兩個線程的數據是相同的,所以這不是問題。
我的推理在這裏是否正確?如果沒有,有沒有辦法使用同步塊而不會導致大的性能下降?一次只有一個線程訪問地圖感覺像是過度殺傷。
感謝您的想法,非常教育。 – 2013-02-14 09:40:43