繁体   English   中英

Java同步块与并发HashMap与Collections.synchronizedMap

[英]Java synchronized block vs concurrentHashMap vs Collections.synchronizedMap

说如果有一个同步方法,并且在该方法内,我将更新哈希表,如下所示:

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

现在,当method1运行并且哈希表正在重新填充时,如果有其他线程正在努力获取哈希表的值,我认为它们将被阻塞?

现在,不使用同步方法,而是将哈希图更改为ConcurrentHashMap,如下所示,其行为是什么?

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

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

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

与所有改进一样,仍然需要权衡一些。 在整个Map上运行的方法的语义(例如size和isEmpty)已被稍微削弱,以反映集合的并发性质。 由于大小的结果在计算时可能已经过时,因此它实际上只是一个估计,因此允许大小返回近似值,而不是精确的计数。 乍一看,这似乎令人不安,但实际上,诸如size和isEmpty之类的方法在并发环境中的用处不大,因为这些数量正在移动。



其次, Collections.synchronizedMap

这只是带有同步方法的简单HashMap-我称其为CHM不推荐使用的dute

如果要使对HashMap所有读写操作同步,则需要对所有访问HashMap方法进行synchronize 仅阻止一种方法是不够的。

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

你可能会做

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

读取器会看到一个恒定的映射,因此读取不需要同步,也不会被阻塞。

暂无
暂无

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

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