[英]What kind of the Map interface I should use?
我需要使以下類線程安全:
//Shared among all threads
public class SharedCache {
private Map<Object, Future<Collection<Integer>>> chachedFutures;
{
chachedFutures = new ConcurrentHashMap<>(); //not sure about that
}
public Future<Collection<Integer>> ensureFuture(Object value,
FutureFactory<Collection<Integer>> ff){
if(chachedFutures.containsKey(value))
return chachedFutures.get(value);
Future<Collection<Integer>> ftr = ff.create();
chachedFutures.put(value, ftr);
return ftr;
}
public Future<Collection<Integer>> remove(Object value){
return chachedFutures.remove(value);
}
}
在閱讀了關於ConcurrentHashMap類的文章后,我仍然很難做出正確的決定。
首先,我傾向於使方法ensureFuture
並remove
just synchronized
。 它可以工作,但從性能的角度來看,由於互斥,它不是很好。
我不知道同時訪問Cache
的確切(甚至大約)線程數量以及Cache
的大小。 考慮到
調整這個或任何其他類型的哈希表的大小是一個相對較慢的操作
我沒有指定地圖的初始大小。 還有concurrencyLevel參數。 在這里使用ConcurrentHashMap
還是同步方法就足夠了?
您有以下方法:
public Future<Collection<Integer>> ensureFuture(Object value,
FutureFactory<Collection<Integer>> ff){
if(chachedFutures.containsKey(value))
return chachedFutures.get(value);
Future<Collection<Integer>> ftr = ff.create();
chachedFutures.put(value, ftr);
return ftr;
}
public Future<Collection<Integer>> remove(Object value){
return chachedFutures.remove(value);
}
有幾點需要注意:
ensureFuture
在這種情況下不同步,一個線程可能調用containsKey
返回true
但在執行下一行之前,另一個線程可能會刪除與該鍵相關的條目。 這可能會導致競爭條件,因為它是check-then-act
場景。 也檢查這個。chachedFutures.put(value, ftr)
但 IMO 您應該使用chachedFutures.putIfAbsent(value, ftr)
。 對於此方法, if the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value
。 使用它您還可以避免包含檢查。在這里使用 ConcurrentHashMap 還是同步方法就足夠了?
這取決於與 HashMap 相比,由於大量簿記活動等,CHM 需要更多內存。另一種選擇是使用Collections.synchronizedMap
,它將在常規HashMap
上提供同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.