【问题标题】:Iterate over an ArrayList of more than 5000 object instances [closed]迭代超过 5000 个对象实例的 ArrayList [关闭]
【发布时间】:2014-07-08 12:10:35
【问题描述】:

我使用JDK5,操作系统为Windows7,内存为6gb,双核处理器

我有一个包含 5000 条记录的数组列表,它的大小最终会增加。

由于这个 ArrayList 可以包含大量数据,所以如果我将列表分为两部分并在 java 并发包的 FututreTask 的帮助下生成两个线程 T1 和 T2,这将是一个好方法,所以线程(T1 和 T2)可以并行迭代这个 ArrayList 并更快地完成它。

请提供建议,因为我无法就实现 FutureTask 以迭代 Arraylist 得出结论。

【问题讨论】:

  • 增加什么? 5000 个对象并不是很多(当然取决于对象)。 50000 个对象仍然不是很多(仍然取决于对象)。您需要更具体地了解您将要处理的内容,然后人们才能就如何处理它向您提供架构建议。
  • BlockingDeque 是在 java 中实现多线程工作者模式的一种简单而有效的方法。每个线程在准备就绪时从队列中读取一项工作并进行处理。
  • 没有具体限制,我的意思是我从返回大量数据的数据库中获取记录并将其存储在 Arraylist 中。现在,当我尝试遍历此列表时,它需要 10 多秒,因为它返回了许多字段。
  • 很遗憾不能使用 JDK8,这正是流 API 的设计目的。事实上,sourceforge.net/projects/streamsupport 这会有所帮助吗?
  • 跳入多线程有点危险,除非您了解它将如何帮助您,否则您不应该这样做。在上述情况下,可能没有太多收获。当您有大量通信或“磁盘”I/O 时更有用。

标签: java multithreading arraylist


【解决方案1】:

我写这个答案是假设您使用单个 CPU 来执行您的程序。只需使用一个 for 循环。当您可以将 CPU 任务与 I/O 任务交错或交错多个 I/O 任务时使用线程。在这些情况下线程的优势在于,当一个空闲时(例如文件读取等同步 I/O 调用),另一个(例如您的 CPU 任务)可以接管。

如果你在你的情况下使用线程,CPU 必须在线程切换上花费额外的时间。

【讨论】:

  • 谢谢.. 我同意,但有没有其他选择,我只是想知道一种更快的方法来迭代列表。
  • 简短的回答是否定的...访问大小为 n 的列表中的每个项目都是 Omega(n) 的顺序...也就是说您无论如何都必须访问每个元素...长答案是肯定的,只有当你有多个计算资源时,这些对子数组的访问是相互独立的......
【解决方案2】:

正如您在评论中所读到的,您是否使用像 Hibernate 这样的持久性 API 从数据库中获取列表?如果不是,那么迭代 ResultSet 并将其存储在列表中显然是一种开销,因为您需要稍后对其进行迭代。

谈到实际问题,您可以将列表分成两部分并使用线程,但根据您正在执行的操作,会有一些缺点。如果您在迭代时对列表进行一些操作,例如将其写入文件,您的列表顺序将会丢失。

【讨论】:

  • 谢谢,是的,我正在使用 Hibernate 从可以返回大量数据的数据库中检索数据。除了填充另一个列表以便它可以在前端用于列出 GUI 中的值之外,我没有执行任何 I/O 操作。
  • 如果这符合您的设计模式,您可以使用从前端数据库中获得的相同列表。由于在这里使用额外的线程并没有多大帮助,因此您必须查看较小的开销并消除它们。如果您要填充不同类型的列表,例如 List 中的 List,那么除了循环之外别无选择。
【解决方案3】:

我认为你可以使用更多的线程,这样你就可以更快地完成任务。

【讨论】:

  • 谢谢,我想我可以利用 Future Task 并完成任务。
  • 如果您只有一个处理器,则不会...当您想将 CPU 处理与 I/O 处理交错时,线程很有用...它没有多大用处(实际上读起来更慢)您使用线程来交错两个(或更多)CPU 处理任务...
猜你喜欢
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 2012-10-08
  • 2019-07-27
  • 1970-01-01
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多