我需要迭代一个大的 ArrayList
(约 50,000 个条目),我需要使用多个线程来相当快地完成这项工作。
但我需要每个线程都从一个唯一的索引开始,这样就不会有两个线程重复访问列表的同一部分。会有一个batchSize
的 100
所以每个线程都会从它的 startIndex
开始循环至 startIndex + 100
.
有什么办法可以实现吗?请注意,我这里只执行读操作,不执行写操作。列表中的每个条目只是一个字符串,它实际上是一个 SQL 查询,然后我通过 JDBC 对数据库执行该查询。
最佳答案
如果您只想读取List
,而不是改变它,您可以简单地定义您的Runnable
来获取List
和一个startIndex
作为构造函数参数。只要没有线程同时修改它,并发读取 ArrayList
(即使是相同的索引)也没有危险。
为了安全起见,请务必将您的ArrayList
包装在对Collections.unmodifiableList()
的调用中并将 that List
传递给您的 Runnable
。这样您就可以确信线程不会修改支持 ArrayList
。
或者,您可以在主线程中构造子列表(使用 List.subList()
),这样您就不需要将 startIndex
传递给每个线程。但是,您仍然希望在这样做之前使子列表不可修改。一个六个,另一个六个。
更好的方法是使用 Guava的 ImmutableList
;它自然是线程安全的。
还有 parallel streams在 Java 8 中,但要注意这个解决方案;它们功能强大,但很容易出错。
关于java - 如何在 Java 中使用多个线程迭代一个集合,其中没有两个线程迭代集合的同一部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30054237/