并发哈希表:检查大小

9

Concurrent Hashmap可以解决HashMap中的同步问题。因此,如果我们使用synchronized关键字与HashMap一起使用,添加和删除将会很快。但是,如果多个线程检查ConcurrentHashMap的大小,那么检查HashMap的大小还需要同步关键字吗?如下所示:

public static synchronized getSize(){
     return aConcurrentHashmap.size();
}  
5个回答

11

concurentHashMap.size()将返回调用时已知的大小,但当您使用该数字时,它可能是过时的值,因为另一个线程在此期间添加/删除了项目。

然而,ConcurrentMaps的整个目的是您不需要同步它,因为它是一个线程安全的集合。


2

除非您需要原子地执行多个操作,否则不需要在ConcurrentHashMap中使用synchronized,这种情况非常罕见。

如果只是获取大小,可以在没有同步的情况下调用它。


为了澄清何时会在ConcurrentHashMap中使用同步...

假设您有一个昂贵的对象需要按需创建。您希望进行并发读取,但也希望确保值仅被创建一次。

public ExpensiveObject get(String key) {
    return map.get(key); // can work concurrently.
}

public void put(String key, ExepensiveBuilder builder) {
    // cannot use putIfAbsent because it needs the object before checking.
    synchronized(map) {
        if (!map.containsKey(key))
            map.put(key, builder.create());
    }
}

注意:这需要所有写操作都同步,但读操作仍然可以并发进行。

ConcurrentHashMap 在内部进行了同步。在其上添加自己的同步块可能无法达到您想要的效果。 - krock
@krock 你必须小心使用它。这里附上一个例子。 - Peter Lawrey

2

你可以简单地调用aConcurrentHashmap.size()。然而,你必须记住,当你得到答案的时候,它可能已经过时了。如果另一个线程同时修改了映射,就会发生这种情况。


0
ConcurrentHashMap是一种安全的容器,它不会产生任何并发修改异常。它非常适合多线程操作。整个ConcurrentHashMap的实现与HashMap相同,但在检索元素时,HashMap会锁定整个映射,限制进一步的修改,从而导致并发修改异常。但是,在ConcurrentHashMap中,锁定发生在桶级别,因此不会出现并发修改异常的情况。
所以,回答你的问题,检查ConcurrentHashMap的大小没有帮助,因为它基于你在映射上编写的操作或修改代码进行链接。它具有与HashMap相同的size方法。

0
ConcurrentHashMap 的设计者考虑到给予个别操作(如:get()、put() 和 remove())更高的权重,而不是像 isEmpty() 或 size() 这样操作整个 HashMap 的方法。这是因为一般情况下调用这些方法的机会较少。
在此不需要对 size() 进行同步。我们可以通过调用 concurentHashMap.size() 方法来获取大小。由于其他线程可能同时修改映射,因此该方法可能返回过时的值。但是,这被明确假定为已破坏,因为这些操作被降低了优先级。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接