为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 hashmap 不是线程安全的?

为什么 hashmap 不是线程安全的?

狐的传说 2021-10-13 16:25:57
import java.util.HashMap;import java.util.Map;import java.util.concurrent.*;public class TestLock {    private static ExecutorService executor = Executors.newCachedThreadPool();    private static Map<Integer, Integer> map = new HashMap<>(1000000);    private static CountDownLatch doneSignal = new CountDownLatch(1000);    public static void main(String[] args) throws Exception {        for (int i = 0; i < 1000; i++) {            final int j = i;            executor.execute(new Runnable() {                @Override                public void run() {                    map.put(j, j);                    doneSignal.countDown();                }            });        }        doneSignal.await();        System.out.println("done,size:" + map.size());    }}有人说并发时hashmap插入不安全。因为hashmap会进行扩容操作,但是我这里把size设置为1000000,只会扩容到750000。我在这里做了 1000 次插入,所以我不会扩展它。所以应该没有问题。但是结果总是小于1000,哪里出错了?
查看完整描述

3 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

“因为 hashmap 会执行扩容操作”不仅HashMap是线程不安全的原因。

您必须参考 Java 内存模型来了解它可以提供什么保证。

这种保证之一是可见性。这意味着除非满足特定条件,否则在一个线程中所做的更改可能在其他线程中不可见。


查看完整回答
反对 回复 2021-10-13
?
青春有我

TA贡献1784条经验 获得超8个赞

那么问题标题并没有真正描述您的要求。无论如何,

在这里,您已将容量设置为 1000000。不是大小。

容量:最初在这个哈希图中有多少个插槽。基本上是空插槽。

大小:地图中填充的元素数量。

因此,即使您将容量设置为 1000000,最终也没有那么多元素。所以map中填充的元素个数会通过.size()方法返回。它与并发问题无关。是的,由于多种原因,HashMap 不是线程安全的。


查看完整回答
反对 回复 2021-10-13
  • 3 回答
  • 0 关注
  • 227 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信