如果在linkedhashmap上并行执行多个put操作会发生什么?



我有样例代码:

Map<Integer, String> hs = new LinkedHashMap<>();
IntStream.range(0,1000).parallel().forEach(value -> hs.put(value, "value"));
System.out.println(hs.size());

这是永远不会返回大小为1000,因为我理解linkedhashmap不是线程安全的,当我使用Collections.synchronizedMap(new LinkedHashMap<>());时,大小总是1000,因为它是线程安全的。

我想了解当多个线程试图将数据放入其中时,在linkedhashmap放置操作的情况下会发生什么?它怎么有更少的元素?

问自己如何hashmap。

顾名思义:by "linking"对象转换成某种"链",并使用跟踪"下一个"的数据结构。

元素。现在想象链结束于对象X,两个不同的线程进来并添加了一个应该在X之后的新条目。这两个线程都更新了数据结构,第二个线程覆盖了第一个线程所做的。

换句话说:应该添加两个新元素作为HashMap键,但实际上只有其中一个成功了,另一个只是丢失了。

这就像两个人把砖头扔进垃圾桶。如果他们不注意,他们可能会同时扔砖头,砖头"碰撞",而不是两个砖头都被扔进垃圾桶。

hs.put(0, "0");
hs.put(1, "1");
hs.put(2, "2");
// hs should be "0 -> 1 -> 2"
hs.put(0, "0");
hs.put(1, "1");
// so sometimes it should be `0.next = 1`
// because it is not thread safe
// `2` should be behind 1, but it cut the queue
// become 0.next = 1; 0.next = 2; `0.next` is assigned twice
// so the `1` is lost!
hs.put(2, "2");
// hs will be "0 -> 2"