【问题标题】:Hashmap and hashtable in multithreaded environment多线程环境下的Hashmap和hashtable
【发布时间】:2009-09-01 10:53:27
【问题描述】:

我对这两个集合在多线程环境中的行为感到非常困惑。

哈希表是同步的,这意味着不会有 2 个线程同时更新它的值,对吧?

【问题讨论】:

    标签: java multithreading thread-safety hashtable hashmap


    【解决方案1】:

    查看ConcurrentHashMaps 以获得线程安全映射。

    它们提供了 HashTable 的所有功能,性能非常接近 HashMap。

    通过不使用地图范围的锁来获得性能,该集合默认维护一个包含 16 个锁的列表,每个锁用于锁定地图的单个存储桶。您甚至可以配置存储桶的数量 :) 调整这可以根据您的数据提高性能。

    Brian Goetz 的 Java Concurrency in Practice 我不能推荐足够多的东西 http://jcip.net/

    每次阅读时我都会学到一些新东西。

    【讨论】:

      【解决方案2】:

      没错,HashTable 是同步的,这意味着在多线程环境中使用它是安全的(许多线程访问同一个 HashTable)如果两个线程同时尝试更新 hashtable,其中一个将不得不等待其他线程完成他的更新。

      HashMap 不同步,所以比较快,但是在多线程环境下会出现问题。

      【讨论】:

        【解决方案3】:

        还要注意 Hashtable 和 Collections.synchronizedMap 仅对单个操作是安全的。任何涉及多个键或 check-then-act 的操作都需要是原子的,不是,并且需要额外的客户端锁定。

        例如,如果没有额外的锁定,您不能编写以下任何方法:

        • 交换两个不同键的值:swapValues(Map, Object k1, Object k2)

        • 将参数附加到键的值:appendToValue(Map, Object k1, String suffix)

        是的,所有这些都包含在 JCIP 中:-)

        【讨论】:

        • ConcurrentMapMap 添加了一些非常有用的方法。
        【解决方案4】:

        是的,所有方法都是原子完成的,但 values() 方法不是(请参阅docs)。

        Paul 比我更快地向您推荐了 java.util.concurrent 包,它为您提供了适用于多线程环境的非常精细的控制和数据结构。

        【讨论】:

        • 只有当我们有实例变量时才会出现问题,对吗?在方法签名中声明和使用的变量在多线程环境中不会有问题。如有错误请指正。
        • 实例变量可能更快出现问题,但这不是问题。问题是在没有任何类型的控件的情况下共享变量。我使用静态 ConcurrentHashMap 没有问题(我完全同意 Paul 的回答):)
        • 方法调用或构造函数的参数不能是实例(或类)变量。
        【解决方案5】:

        哈希表是同步的,但它们是一个旧的实现,您几乎可以说它已被弃用。此外,它们不允许空键(也许也不是空值?不确定)。

        一个问题是,虽然每个方法调用都是同步的,但大多数有趣的操作需要多个调用,因此您必须围绕多个调用进行同步。

        通过调用 HashMap 可以获得类似级别的同步:

        Map m = Collections.synchronizedMap(new HashMap());
        

        它在同步方法调用中包装了一个映射。但这与 Hashtable 有相同的并发缺点。

        正如 Paul 所说,ConcurrentHashMaps 为线程安全映射提供了额外有用的原子更新方法。

        【讨论】:

        • 哈希表还没有被弃用(不知道为什么),但他们实现的字典接口被认为是过时的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-01
        • 1970-01-01
        • 2014-08-31
        • 1970-01-01
        • 2013-07-27
        • 2010-11-15
        • 1970-01-01
        相关资源
        最近更新 更多