Pahalı nesneler oluşturmayı ve onları Map
'da önbelleğe almayı içeren bazı üçüncü taraf kitaplık koduyla uğraşıyorum. Varolan uygulama farklı keys
için Foos
bağımsız oluşturulabilir zamanAnahtar sözcük engelleme Java'daki Harita
lock.lock()
try {
Foo result = cache.get(key);
if (result == null) {
result = createFooExpensively(key);
cache.put(key, result);
}
return result;
} finally {
lock.unlock();
}
gibi bir şey Açıkçası bu en iyi tasarım olmadığı.
Bulunduğum kesmek kullanmaktır bir Map
Futures
ait:
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);
}
Ama bu görünüyor ... biraz hacky, iki nedenden dolayı:
- eser keyfi toplanmış yapılır iplik. numaralı işin, bu anahtarı almayı deneyen ilk iş parçacığına sahip olmasından memnuniyet duyarız, özellikle de bu nedenle engellenecektir.
Map
tam olarak doldurulduğunda bile, sonuçlarına ulaşmak için halaFuture.get()
geçer. Bunun çok ucuz olduğunu umuyorum ama çirkin.
Ne istediğinizi anahtar bir değere sahip kadar belirli bir anahtar için alır engeller bir Map
ile cache
yerine, ancak diğer bu arada alır sağlamaktır. Böyle bir şey var mı? Veya birisiFutures
için daha temiz bir alternatif var mı?
Mağaza anahtar nesneleri ve anahtar nesneler kendilerini kilidi:
kullanın:
Sınıfındaki bunu beyan? Anahtarlar intrinsikse (int, 'String' vb.) Sarın. –
Bu neredeyse bir Guava ['Striped'] istediğiniz gibi geliyor (http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/util/concurrent/Striped.html), nesnelerden kilitlere bir harita gibi davranır. –