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 内存模型来了解它可以提供什么保证。
这种保证之一是可见性。这意味着除非满足特定条件,否则在一个线程中所做的更改可能在其他线程中不可见。
青春有我
TA贡献1784条经验 获得超8个赞
那么问题标题并没有真正描述您的要求。无论如何,
在这里,您已将容量设置为 1000000。不是大小。
容量:最初在这个哈希图中有多少个插槽。基本上是空插槽。
大小:地图中填充的元素数量。
因此,即使您将容量设置为 1000000,最终也没有那么多元素。所以map中填充的元素个数会通过.size()
方法返回。它与并发问题无关。是的,由于多种原因,HashMap 不是线程安全的。
添加回答
举报
0/150
提交
取消