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

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,哪里出错了?


狐的传说
浏览 228回答 3
3回答

ABOUTYOU

“因为 hashmap 会执行扩容操作”不仅HashMap是线程不安全的原因。您必须参考 Java 内存模型来了解它可以提供什么保证。这种保证之一是可见性。这意味着除非满足特定条件,否则在一个线程中所做的更改可能在其他线程中不可见。

青春有我

那么问题标题并没有真正描述您的要求。无论如何,在这里,您已将容量设置为 1000000。不是大小。容量:最初在这个哈希图中有多少个插槽。基本上是空插槽。大小:地图中填充的元素数量。因此,即使您将容量设置为 1000000,最终也没有那么多元素。所以map中填充的元素个数会通过.size()方法返回。它与并发问题无关。是的,由于多种原因,HashMap 不是线程安全的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java