我有一个非常大ArrayList
的对象,它在单个线程中顺利执行。但执行时间是因素。
让我的列表有 50 个元素,我有 3 个线程,
我希望第一个线程将处理 0 到 15,第二个线程将处理 16 到 31,其余的进程将由第三个线程处理。
可能吗?
我有一个非常大ArrayList
的对象,它在单个线程中顺利执行。但执行时间是因素。
让我的列表有 50 个元素,我有 3 个线程,
我希望第一个线程将处理 0 到 15,第二个线程将处理 16 到 31,其余的进程将由第三个线程处理。
可能吗?
技术上可以做到这一点,但这不是一个好主意:
任何固定分区都有工作线程工作负载不平衡的风险。完成计算的并行部分所花费的时间是每个工作线程的时间的最大值。
这ArrayList
可能成为争用瓶颈,尤其是在线程需要更新它的情况下。
更好的方法是使用队列机制,所有工作人员都从同一个队列中工作。实现这一点的一种简单方法是使用ExecutorService
带界工作池。(fork-join 框架是另一种可能性,尽管它更适合于任务之间存在依赖关系的动态或递归任务。)
对于您的情况,最佳方法是使用一个线程从 excel 文件中读取 url,并将其放入容量有限的 ArrayBlockingQueue 中。启动几个工作线程,它们一个一个地获取 url 并抓取引用的站点。标准线程池无济于事,因为每个工作在访问站点时都需要阻塞,而线程池不喜欢它们的线程被阻塞。唯一需要调整的参数是工作线程的数量。尝试 10、100、1000、10000 以找出最快的配置。如果有几千个线程,内存已经耗尽,但没有达到最佳值,那么切换到像 Netty 这样的 NIO 库。