複数のスレッドが同時に同じリソースにアクセスしようとしていないことを確認する必要があります。私はこれらのリソースをたくさん持っているので、スレッドが不必要にお互いをブロックしないように、(1 つのグローバル ロックではなく) リソースごとに個別のロック オブジェクトが必要です。
Eddie は、 https://stackoverflow.com/a/659939/82156ConcurrentMap.putIfAbsent()
を使用して、これに対する優れたソリューションを提示します。
// From https://stackoverflow.com/a/659939/82156
public Page getPage(Integer id) {
Page p = cache.get(id);
if (p == null) {
synchronized (getCacheSyncObject(id)) {
p = getFromDataBase(id);
cache.store(p);
}
}
}
private ConcurrentMap<Integer, Integer> locks = new ConcurrentHashMap<Integer, Integer>();
private Object getCacheSyncObject(final Integer id) {
locks.putIfAbsent(id, id);
return locks.get(id);
}
ただし、その実装の問題の 1 つは、ハッシュマップが無制限に大きくなることです。同時実行性を台無しにすることなく、スレッドが完了したときにハッシュキーを削除する方法はありますか?