Java synchronized block vs concurrentHashMap vs Collections.synchronizedMap

时间:2012-09-27 19:20:08

标签: java synchronization

Say如果有一个synchronized方法并且在该方法中,我更新一个这样的hashmap:

public synchronized void method1()
{
    myHashMap.clear();
    //populate the hashmap, takes about 5 seconds.
}

现在当method1正在运行并且正在重新填充hashmap时,如果还有其他线程要获取hashmap的值,我认为它们会被阻塞吗?

现在,如果我将hashmap更改为ConcurrentHashMap,而不是使用sync方法,那么行为是什么?

public void method1()
{
     myConcurrentHashMap.clear();
    //populate the hashmap, takes about 5 seconds.
}

如果我使用Collections.synchronizedMap怎么办?它是一样的吗?

3 个答案:

答案 0 :(得分:13)

CHM(ConcurrentHashMap),而不是同步公共锁上的每个方法,限制对单个线程的访问 它一次使用一种称为锁定条带的更细粒度的锁定机制,以允许更大程度的共享访问。任意多的阅读线程 可以同时访问地图,读者可以同时访问地图 作家和有限数量的作家可以同时修改地图。结果 并发访问下的吞吐量要高得多,性能损失很小 单线程访问。 ConcurrentHashMap以及其他并发集合进一步改进 通过提供不抛出的迭代器来实现同步集合类 ConcurrentModificationException,从而消除了锁定集合的需要 在迭代期间。

与所有改进一样,仍有一些权衡。方法的语义 在整个Map上运行,例如size和isEmpty,略有不同 削弱以反映集合的并发性质。由于尺寸的结果 在计算时它可能已经过时,它实际上只是一个估计,所以大小 允许返回近似值而不是精确计数。虽然起初这个 可能看起来很令人不安,实际上像size和isEmpty这样的方法远没那么有用 并发环境,因为这些数量是移动目标。



其次,Collections.synchronizedMap

这只是带有同步方法的简单HashMap - 我把它称为对CHM弃用的dute

答案 1 :(得分:8)

如果您希望对HashMap同步进行所有读写操作,则需要将synchronize放在访问HashMap的所有方法上;仅阻止一种方法是不够的。

ConcurrentHashMap允许线程安全访问您的数据而无需锁定。这意味着您可以在一个线程中添加/删除值,同时在另一个线程中获取值而不会遇到异常。另请参阅documentation of ConcurrentHashMap

答案 2 :(得分:0)

你可以做到

volatile private HashMap map = newMap();

private HashMap newMap() {
    HashMap map = new HashMap();
    //populate the hashmap, takes about 5 seconds
    return map;
}

public void updateMap() {
    map = newMap();
}

读者看到一个常量映射,因此读取不需要同步,也不会被阻止。