Некоторое время назад я создал кэш с помощью Soft References, но, пытаясь устранить ошибку, меня беспокоит, что на самом деле я сделал это неправильно и удаляю объекты, когда этого не должно быть.Вот как я это сделал:
private static final Map<String, SoftReference<Buffered>> imageMap =
new HashMap<String,SoftReference<Buffered>>();
public static synchronized Buffered addImage(String sum, final byte[] imageData)
{
SoftReference<Buffered> bufferedRef = imageMap.get(sum);
Buffered buffered;
if (bufferedRef!=null)
{
//There are no longer any hard refs but we need again so add back in
if(bufferedRef.get()==null)
{
buffered = new Buffered(imageData, sum);
imageMap.put(sum, new SoftReference(buffered));
}
else
{
buffered=bufferedRef.get();
}
}
else
{
buffered = new Buffered(imageData, logDescriptor, sum);
imageMap.put(sum, new SoftReference(buffered));
}
return buffered;
}
public static Buffered getImage(String sum)
{
SoftReference<Buffered> sr = imageMap.get(sum);
if(sr!=null)
{
return sr.get();
}
return null;
}
Таким образом, идея заключается в том, что вызывающий процесс может добавлять новые буферизованные объекты, которые можно идентифицировать / искать по ключевой сумме, тогда, пока этот буферизованный объектесли он используется хотя бы одним объектом, он не будет удален с карты, но если он больше не используется какими-либо объектами, он может быть сборщиком мусора, если объем памяти будет ограничен.
Но, глядя на мой кодтеперь важно то, что на ключевую сумму поля всегда ссылаются где-то еще (что не всегда так)
РЕДАКТИРОВАТЬ: Итак, я попробовал решение Колина, но я немного озадачен, потому что putIfAbsent () некажется, не вернуть добавленную стоимость.Я изменил свой метод addImage, чтобы получить некоторую отладочную информацию
public static synchronized Buffered addImage(String sum, final byte[] imageData)
{
Buffered buffered = new Buffered(imageData, sum);
Buffered buffered2 = imageMap.get(sum );
Buffered buffered3 = imageMap.putIfAbsent(sum,buffered );
Buffered buffered4 = imageMap.get(sum );
System.out.println("Buffered AddImage1:"+buffered);
System.out.println("Buffered AddImage2:"+buffered2);
System.out.println("Buffered AddImage3:"+buffered3);
System.out.println("Buffered AddImage4:"+buffered4);
return buffered2;
}
возвращает
Buffered AddImage1:com.Buffered@6ef725a6
Buffered AddImage2:null
Buffered AddImage3:null
Buffered AddImage4:com.Buffered@6ef725a6
Таким образом, он ясно показывает, что экземпляр Buffered не был для начала, успешно создан и добавлен, нообязательно должен быть возвращен putIfAbsent?