java - 如何在 Java 中使用多个线程迭代一个集合,其中没有两个线程迭代集合的同一部分?

标签 java multithreading collections iteration

我需要迭代一个大的 ArrayList (约 50,000 个条目),我需要使用多个线程来相当快地完成这项工作。

但我需要每个线程都从一个唯一的索引开始,这样就不会有两个线程重复访问列表的同一部分。会有一个batchSize100所以每个线程都会从它的 startIndex 开始循环至 startIndex + 100 .

有什么办法可以实现吗?请注意,我这里只执行读操作,不执行写操作。列表中的每个条目只是一个字符串,它实际上是一个 SQL 查询,然后我通过 JDBC 对数据库执行该查询。

最佳答案

如果您只想读取List,而不是改变它,您可以简单地定义您的Runnable来获取List和一个startIndex 作为构造函数参数。只要没有线程同时修改它,并发读取 ArrayList(即使是相同的索引)也没有危险。

为了安全起见,请务必将您的ArrayList 包装在对Collections.unmodifiableList() 的调用中并将 that List 传递给您的 Runnable。这样您就可以确信线程不会修改支持 ArrayList

或者,您可以在主线程中构造子列表(使用 List.subList() ),这样您就不需要将 startIndex 传递给每个线程。但是,您仍然希望在这样做之前使子列表不可修改。一个六个,另一个六个。

更好的方法是使用 GuavaImmutableList ;它自然是线程安全的。

还有 parallel streams在 Java 8 中,但要注意这个解决方案;它们功能强大,但很容易出错。

关于java - 如何在 Java 中使用多个线程迭代一个集合,其中没有两个线程迭代集合的同一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30054237/

相关文章:

java - 将实体移动到另一个列表

Java声音API : Attempt to Do Live Microphone Input Monitoring is Slow

java - 如何在Spring Boot中用自己的mock替换BeanFactory中的bean?

java - 如何安全地将字符串组合到文件路径并打开文件写入器?

multithreading - 使用 Quarkus 启动工作线程的正确方法?

c++ - 远程线程执行

java - 在 Java 中用两个线程打印数字 1-20

java集合排序问题

java - Java中基于属性的压缩ArrayList

Java: get+clear atomic for map