高価なオブジェクトを作成し、Map. 既存の実装は次のようなものです
lock.lock()
try {
Foo result = cache.get(key);
if (result == null) {
result = createFooExpensively(key);
cache.put(key, result);
}
return result;
} finally {
lock.unlock();
}
明らかにFoos、異なるkeysものを個別に作成できる場合、これは最適な設計ではありません。
私の現在のハックは、 of を使用することMapですFutures:
lock.lock();
Future<Foo> future;
try {
future = allFutures.get(key);
if (future == null) {
future = executorService.submit(new Callable<Foo>() {
public Foo call() {
return createFooExpensively(key);
}
});
allFutures.put(key, future);
}
} finally {
lock.unlock();
}
try {
return future.get();
} catch (InterruptedException e) {
throw new MyRuntimeException(e);
} catch (ExecutionException e) {
throw new MyRuntimeException(e);
}
しかし、これは... 2つの理由から、少しハッキーに思えます:
- 作業は任意のプールされたスレッドで行われます。特にブロックされるので、その特定のキーを取得しようとする最初のスレッドで作業を完了していただければ幸いです。
Mapが完全に入力されている場合でもFuture.get()、結果を取得するために実行します。これはかなり安いと思いますが、醜いです。
私が望むのは、そのキーが値を持つまで特定のキーの取得をブロックするが、その間は他の取得を許可するcacheに置き換えることです。そのようなものは存在しますか?または、誰かがofのよりクリーンな代替手段を持っていますか?MapMapFutures