
问题分析
在原始代码中,executorservice 提交任务后立即执行 system.out.println(map.size())。由于线程池中的线程是并发执行的,主线程不会等待所有子线程完成 put 操作。因此,map.size() 的结果可能小于预期值。
解决方案:使用 ExecutorService.invokeAll()
为了确保在读取 ConcurrentHashMap 的大小之前,所有线程都已完成写入操作,可以使用 ExecutorService.invokeAll() 方法。此方法会阻塞主线程,直到所有提交的任务都执行完毕。
以下是修改后的代码:
import java.util.Map;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;
public class ConcurrentHashMapExample {
public static void main(String[] args) throws InterruptedException {
Map 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());
executorService.shutdown();
}
} 代码解释:
websenB2B是一套经过完善设计的B2B行业网站程序,是windows nt系列环境下最佳的B2B行业网产站解决方案。精心设计的架构与功能机制,适合从个人到企业各方面应用的要求,为您提供一个安全、稳定、高效、易用而快捷的行业网站商务系统。分普及版和商业版等不同版本。一、网胜B2B电子商务系统SP6.2蓝色风格普及版本升级功能说明:1、邮件群发功能:可以选择某一级别的会员,并放入支持html
- Collections.nCopies(4, Executors.callable(runnable)): 创建一个包含 4 个 Callable 对象的集合,每个 Callable 对象都包装了 runnable。Executors.callable() 方法将 Runnable 转换为 Callable。
- executorService.invokeAll(...): 提交 Callable 集合到线程池。invokeAll() 方法会阻塞当前线程,直到所有任务都执行完成。
- System.out.println(map.size()): 在所有线程完成写入后,打印 ConcurrentHashMap 的大小。
注意事项:
- 在使用 ExecutorService 后,务必调用 executorService.shutdown() 方法来关闭线程池,释放资源。
- invokeAll() 方法会抛出 InterruptedException 异常,需要进行处理。
总结
通过使用 ExecutorService.invokeAll() 方法,可以确保在读取 ConcurrentHashMap 的大小之前,所有线程都已完成写入操作,从而避免数据不一致的问题。这种方法适用于需要确保所有并发任务完成后再进行后续处理的场景。在并发编程中,理解线程的执行顺序和同步机制至关重要,选择合适的工具和方法可以有效地避免潜在的问题。








