如何HashMap.computeIfAbsent下的多线程使用失败?

问题描述 投票:2回答:2

为java.util.HashMap中的文档明确指出:“如果多个线程访问哈希映射同时,与线程中的至少一个在结构上修改了该映射,它必须保持外部同步”。

然而,考虑你使用地图作为缓存来减少不可变对象的创建,其中只有computeIfAbsent被称为在HashMap中(没有除去/驱逐)的使用情况。而你所关心的唯一的事情就是computeIfAbsent返回一个有效的对象;你们不关心,如果computeIfAbsent偶尔会产生额外的对象或覆盖现有条目。

什么是可能发生的最糟糕?在我的测试散有没有负面影响。 (我会用ConcurrentHashMap的,但正是在这种情况下,使用相对较慢。)

java multithreading hashmap thread-safety
2个回答
3
投票

这里的问题:如果有的话,该线程安全将是一个实现细节。它可能发生在制定出一个JVM版本,但略有不同,或者在java.util.HashMap中的一些其他版本的“关”。

引用另一个answer

话虽这么说,最常用的Map实现,具体的HashMap不是线程安全的。加入来自不同线程的元件可以离开处于不一致的状态,其中例如在地图已插入元件不能被检索虽然尺寸()表示它们是本。

换句话说,即使你没有今天的问题,只需切换到不同的Java版本理论上可以打开你的设计失败。

请记住:你唯一的保证是Map接口。您正在使用具有被多个线程更新了一些内部结构的容器。如果出现这种情况,以不引起矛盾则是纯粹的巧合。

如果读取和写入的HashMap会在多线程设置“只是工作”,为什么会被一个ConcurrentHashMap在第一时间要求?


1
投票

什么是可能发生的最糟糕?

怎么样,线程A处于computeIfAbsent(K1,...)调用,而线程B同时在GET(K2)和GET(K2)返回错误的值?

我不知道这是可能发生的最糟糕的,但它绝对事情可能发生。

© www.soinside.com 2019 - 2024. All rights reserved.