Java HashMap.ComputeFabSent在多线程使用下如何失败?

Java HashMap.ComputeFabSent在多线程使用下如何失败?,java,multithreading,hashmap,thread-safety,Java,Multithreading,Hashmap,Thread Safety,java.util.HashMap的文档清楚地指出:“如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改映射,那么它必须在外部同步。” 但是,考虑使用map作为缓存来减少不可变对象创建的情况,其中仅在HASMAP上调用CuffTeFielt(不删除/删除)。你唯一关心的是ComputeFabSent返回一个有效的对象;您不在乎ComputeFabSent是否偶尔生成额外对象或覆盖现有条目 可能发生的最坏情况是什么?在我的随意测试中,没有负面影响。(我会使用ConcurrentHas

java.util.HashMap的文档清楚地指出:“如果多个线程同时访问一个哈希映射,并且至少有一个线程在结构上修改映射,那么它必须在外部同步。”

但是,考虑使用map作为缓存来减少不可变对象创建的情况,其中仅在HASMAP上调用CuffTeFielt(不删除/删除)。你唯一关心的是ComputeFabSent返回一个有效的对象;您不在乎ComputeFabSent是否偶尔生成额外对象或覆盖现有条目


可能发生的最坏情况是什么?在我的随意测试中,没有负面影响。(我会使用ConcurrentHashMap,但在这个用例中相对较慢。)

这里的问题是:如果有的话,线程安全将是一个实现细节。它可能恰好适用于一个JVM版本,但可能略有不同, 或者在其他版本的java.util.HashMap中使用“off”

引用另一条:

也就是说,最常用的Map实现,特别是HashMap,都不是线程安全的。添加来自不同线程的元素可能会使映射处于不一致的状态,例如,插入的元素无法检索,尽管size()显示它们存在

换句话说:即使您现在没有问题,仅仅切换到另一个java版本理论上可能会导致您的设计失败

记住:你唯一的保证就是地图界面。您正在使用一个容器,该容器具有一些由多个线程更新的内部结构。如果这种情况发生在而不是导致不一致,那么这就是纯粹的巧合

如果读取和写入HashMap在多线程设置中“正常工作”,那么为什么首先需要ConcurrentHashMap

可能发生的最坏情况是什么

线程A在ComputeFabSent(k1,…)调用中,而线程B同时在get(k2)中,并且get(k2)返回错误的值


我不知道这是否是可能发生的最坏情况,但这肯定是可能发生的事情。

一件事是,
如果不存在
部分可能是不可预测的(即,您的缓存对象可能会被计算多次)。不太确定涉及多个键时的行为(如果对不同键的并发操作导致不一致,情况肯定会更糟)如果映射中没有k的条目,ComputeFabSent会将函数的结果插入映射中。对我来说,这听起来像是结构上的改变——例如,它偶尔会导致重新调试。传说中有一个旧版本的HashMap可以在不同步的情况下进行livelock。