简体   繁体   English

我应该使用什么样的 Map 界面?

[英]What kind of the Map interface I should use?

I need to make the following class thread-safe:我需要使以下类线程安全:

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

}

After reading the article about the ConcurrentHashMap class it's still difficult for me to make a right decision.在阅读了关于ConcurrentHashMap类的文章后,我仍然很难做出正确的决定。

Firstly, I tended to make the methods ensureFuture and remove just synchronized .首先,我倾向于使方法ensureFutureremove just synchronized And it would work, but from the performance standpoint it was not very good because of mutually-exclusing.它可以工作,但从性能的角度来看,由于互斥,它不是很好。

I don't know the exact (even approximately) amount of threads having access to the Cache simultaneously and the size of the Cache.我不知道同时访问Cache的确切(甚至大约)线程数量以及Cache的大小。 Taking into account that考虑到

resizing this or any other kind of hash table is a relatively slow operation调整这个或任何其他类型的哈希表的大小是一个相对较慢的操作

I didn't specify the initial size of the map.我没有指定地图的初始大小。 Also the concurrencyLevel parameter.还有concurrencyLevel参数。 Is it justified to use ConcurrentHashMap here or synchronized methods would be enough?在这里使用ConcurrentHashMap还是同步方法就足够了?

You have following methods:您有以下方法:

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

There are some points to be noticed:有几点需要注意:

  1. Suppose method ensureFuture is not synchronized in that case it is possible that one thread invokes containsKey which returns true but before next line is executed another thread may remove the entry respective to that key.假设方法ensureFuture在这种情况下不同步,一个线程可能调用containsKey返回true但在执行下一行之前,另一个线程可能会删除与该键相关的条目。 This can lead to race condition as it is check-then-act scenario.这可能会导致竞争条件,因为它是check-then-act场景。 Check this as well.也检查这个
  2. Also you are using chachedFutures.put(value, ftr) but IMO you should use chachedFutures.putIfAbsent(value, ftr) .此外,您正在使用chachedFutures.put(value, ftr)但 IMO 您应该使用chachedFutures.putIfAbsent(value, ftr) For this method 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 .对于此方法, 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 Using this you can also avoid contains check.使用它您还可以避免包含检查。

Is it justified to use ConcurrentHashMap here or synchronized methods would be enough?在这里使用 ConcurrentHashMap 还是同步方法就足够了?

It depends as CHM needs more memory compared to HashMap due to lot of bookkeeping activities etc. Another alternative is to use Collections.synchronizedMap which will provide synchronization on a regular HashMap .这取决于与 HashMap 相比,由于大量簿记活动等,CHM 需要更多内存。另一种选择是使用Collections.synchronizedMap ,它将在常规HashMap上提供同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM