Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程环境下的Hashmap和hashtable_Java_Multithreading_Thread Safety_Hashtable_Hashmap - Fatal编程技术网

Java 多线程环境下的Hashmap和hashtable

Java 多线程环境下的Hashmap和hashtable,java,multithreading,thread-safety,hashtable,hashmap,Java,Multithreading,Thread Safety,Hashtable,Hashmap,我对这两个集合在多线程环境中的行为感到非常困惑 哈希表是同步的,这意味着没有两个线程会同时更新其值,对吗?确切地说,哈希表是同步的,这意味着在多线程环境中使用它是安全的(许多线程访问同一个哈希表),如果两个线程同时尝试更新哈希表,其中一个线程必须等待另一个线程完成更新 HashMap是不同步的,因此速度更快,但在多线程环境中可能会出现问题。请查看s以获取线程安全映射 它们提供了HashTable的所有特性,性能非常接近HashMap 性能是通过使用地图范围的锁来获得的,集合默认维护16个锁的列表

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


哈希表是同步的,这意味着没有两个线程会同时更新其值,对吗?

确切地说,哈希表是同步的,这意味着在多线程环境中使用它是安全的(许多线程访问同一个哈希表),如果两个线程同时尝试更新哈希表,其中一个线程必须等待另一个线程完成更新

HashMap是不同步的,因此速度更快,但在多线程环境中可能会出现问题。

请查看s以获取线程安全映射

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

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

我不能推荐Brian Goetz在实践中提供足够的Java并发性


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

是的,所有的方法都是原子化的,但values()方法不是(请参阅)


Paul比我推荐java.util.concurrent包的速度更快,它为多线程环境提供了非常好的控制和数据结构。

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

一个问题是,尽管每个方法调用都是同步的,但大多数有趣的操作都需要不止一个调用,因此必须围绕几个调用进行同步

通过调用以下命令,可以为HashMaps获得类似级别的同步:

Map m = Collections.synchronizedMap(new HashMap());
它将映射包装在同步方法调用中。但这与哈希表具有相同的并发缺陷


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

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

例如,如果没有附加锁定,则无法编写以下任何方法:

  • 交换两个不同键上的值:
    swapvalue(映射、对象k1、对象k2)

  • 将参数附加到键处的值:
    appendToValue(映射,对象k1,字符串后缀)


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

中,只有当我们有实例变量时,问题才会出现,对吗?对于在方法签名中声明和使用的变量,在多线程环境中不会出现问题。如果错误,请更正。实例变量可能会更快出现问题,但这不是问题所在。问题是在没有任何类型的控制的情况下共享变量。我使用静态ConcurrentHashMap没有问题(我完全同意Paul的回答):)方法调用或构造函数的参数可能不是实例(或类)变量。
ConcurrentMap
Map
添加了一些非常有用的方法。哈希表还没有被弃用(不确定原因),但是他们实现的字典接口被认为是过时的。