【问题标题】:Why does concurrent put to a ConcurrentHashMap not produce the expected result?为什么并发放入 ConcurrentHashMap 不会产生预期的结果?
【发布时间】:2022-11-03 02:53:36
【问题描述】:

我正在尝试使用多个线程测试对 ConcurrentHashMap 的并发放置,但处理后哈希图的大小不是我所期望的。

我有以下代码将 1000 个条目插入 ConcurrentHashMap:

@Test
public void testThreadSafetyConcurrentHashMap() {
    Map<Integer, Integer> map = new ConcurrentHashMap<>();

    Runnable runnable = () -> {
        for (int i = 0; i < 1000; i++) {
            map.put(i, i);
        }
    };

    ExecutorService executorService = Executors.newFixedThreadPool(4);
    for (int i = 0; i < 4; i++) {
        executorService.submit(runnable);
    }

    System.out.println(map.size());
}

我期待map.size() 电话有 1000 件物品,但我不是每次都得到这个。

有人可以告诉我问题是什么吗?我以为4个线程同时放入1000个项目,最终会导致总共1000个项目?

【问题讨论】:

  • 打印地图大小时是否所有可运行文件都已完成?
  • 启动线程后立即打印尺寸。他们根本没有在短时间内完成。尝试在打印之前添加Thread.sleep(1000);,您会看到。
  • 谢谢两位,你是对的。在我打印尺寸之前没有完成。

标签: java multithreading concurrency hashmap concurrenthashmap


【解决方案1】:

您可以使用ExecutorService.invokeAll() 来确保在检查映射大小之前所有线程都已完成其工作。

invokeAll() 需要 Callable 的集合,我们可以使用 Executors.callable()RunnableCallable 之间进行互操作。

Map<Integer, Integer> map = new ConcurrentHashMap<>();
    
Runnable runnable = () -> {
    for (int i = 0; i < 1000; i++) {
        map.put(i, i);
    }
};
    
ExecutorService executorService = Executors.newFixedThreadPool(4);

executorService.invokeAll(Collections.nCopies(4, Executors.callable(runnable)));
    
System.out.println(map.size());

【讨论】:

    猜你喜欢
    • 2018-02-05
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多