Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.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中的“结构修改”_Java_Multithreading_Hashmap - Fatal编程技术网

Java 理解HashMap中的“结构修改”

Java 理解HashMap中的“结构修改”,java,multithreading,hashmap,Java,Multithreading,Hashmap,它说,在未来 如果多个线程同时访问哈希映射,并且至少有一个 如果有线程在结构上修改映射,则必须对其进行同步 外部。(A)结构修改是指添加或 删除一个或多个映射;仅更改关联的值 实例已包含的键不是结构键 修改) 这似乎表明,更改与实例已包含的键关联的值不需要外部同步。但我认为它不是线程安全的。对吗?出于线程可见性的目的是的,如果有两个线程使用映射进行通信,则需要外部同步。但是,不同步的结构更改有可能完全破坏映射(想象一下,当两个线程放置了一个新映射,并且两个线程都开始重新刷新映射时),而更改一个映

它说,在未来

如果多个线程同时访问哈希映射,并且至少有一个 如果有线程在结构上修改映射,则必须对其进行同步 外部。(A)结构修改是指添加或 删除一个或多个映射;仅更改关联的值 实例已包含的键不是结构键 修改


这似乎表明,更改与实例已包含的键关联的值不需要外部同步。但我认为它不是线程安全的。对吗?

出于线程可见性的目的是的,如果有两个线程使用映射进行通信,则需要外部同步。但是,不同步的结构更改有可能完全破坏映射(想象一下,当两个线程放置了一个新映射,并且两个线程都开始重新刷新映射时),而更改一个映射值的效果就不那么显著了

即使只有一个线程在进行结构修改,如果支持阵列增长/重新灰化,也会出现问题。使用同一数组的其他线程(如果数组已增长,则使用旧数组)可能会遇到更新丢失(线程将值放在旧数组而不是新数组中)、映射消失(线程将值放在数组中,而另一个线程正在重置同一数组,值放在错误的存储桶中)等等

那么什么时候不同步是安全的呢?几乎从来没有。一种安全的情况是预构建的映射,线程只访问“它们的”条目,如

thread1: map.get("A");
thread2: map.put("B", "1");   // Assume "B" was in the map already
thread3: map.get("C");

没有问题,因为没有结构更改,线程没有共享密钥。一旦开始在线程之间共享密钥,就会出现争用条件和可见性问题。如果引入结构更改,这些可见性问题可能会导致地图中的数据丢失。

ArrayList中的类似注释指出,
至少有一个线程在结构上修改地图。
。如果只有一个线程修改地图,它就可以破坏地图?@xingbin想象一个线程在添加元素后开始重新刷新地图,而其他线程仍然看到旧的内部结构。您最终将计算错误的存储桶并看到错误的映射。当结构没有改变时,您就有机会看到/看不到旧的值。