しばらく前にソフト参照を使用してキャッシュを作成しましたが、バグを解決しようとすると、実際には間違って実行され、必要のないときにオブジェクトが削除されるのではないかと心配しています。これは私がそれをした方法です:
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;
}
つまり、呼び出しプロセスは、キーの合計によって識別/検索できる新しいバッファリングされたオブジェクトを追加できます。このバッファリングされたオブジェクトが少なくとも1つのオブジェクトによって使用されている限り、マップから削除されることはありませんが、オブジェクトによって使用されなくなった場合、メモリが不足するとガベージコレクションになる可能性があります。
しかし、今私のコードを見ることが重要なことは、キーフィールドの合計が常にどこか別の場所で参照されていることです(必ずしもそうではありません)。
編集:それで私はコリンの解決策を試しましたが、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によって返される必要がありますか?