我应该使用什么样的Map接口?

时间:2015-09-30 09:18:14

标签: java multithreading

我需要使以下类成为线程安全的:

//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);
    }

}

在阅读关于article课程的ConcurrentHashMap之后,我仍然难以做出正确的决定。

首先,我倾向于将方法ensureFutureremove设为synchronized。它会起作用,但从性能的角度来看,由于相互排斥,它并不是很好。

我不知道同时访问Cache的确切(甚至大约)线程数量以及缓存的大小。考虑到

  

调整此大小或任何其他类型的哈希表是相对较慢的   操作

我没有指定地图的初始大小。还有concurrencyLevel参数。在这里使用ConcurrentHashMap或同步方法是否足够?

1 个答案:

答案 0 :(得分:2)

您有以下方法:

     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);
    }

有一些要注意的地方:

  1. 假设方法ensureFuture未同步,在这种情况下,一个线程可能会调用返回containsKey的{​​{1}},但在执行下一行之前,另一个线程可能会删除相应的条目键。这可能会导致竞争状况,因为它是true情景。也请检查this
  2. 您还在使用check-then-act,但IMO应使用chachedFutures.put(value, ftr)。对于此方法chachedFutures.putIfAbsent(value, ftr)。使用此功能,您还可以避免包含检查。
  3.   

    在此使用ConcurrentHashMap或同步方法是否合理   会不够的?

    由于CHM需要更多内存,因此需要更多内存,因为大量的簿记活动等。另一种方法是使用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来提供常规Collections.synchronizedMap的同步。