【发布时间】:2013-08-14 17:12:41
【问题描述】:
无法理解并行计算列表元素的正确方法是什么,但是在不计算元素时阻塞主线程(并行)。用例:我有一个 URL 链接列表和一个简单的 html 页面解析器,我如何通过并行解析每个页面来减少从给定页面获取信息所需的时间,然后返回一个包含一些 JSON 数据的简单列表.
据我所知,我有两种选择:
与 Futures 的并发方式
我有一个方法可以在 Future 中提取一些 JSON 数据:
def extractData(link: String): Future[JValue] = // some implementation
我只是将它映射到链接列表上,该类型将是 List[Future[JValue]]:
val res: List[Future[JValue]] = listOfLink.map(extractData)
如果我调用 sequence(例如来自 Scalaz,或我自己的实现)遍历此列表并将其转换为 Future[List[JValue]],则链接仍将按顺序处理,但单独的线程不会给出我有任何效率,因为结果我需要得到一个List[JValue]。
尝试使用 ParSeq 进行计算
在这个选项中,我有一个只提取数据的函数:
def extractData(link: String): JValue = // some implementation
但这次在集合上调用.par:
val res: ParSeq[JValue] = listOfLinks.map(extractData)
但是通过这种方式,我不太明白如何在不计算孔列表的情况下阻塞主线程,而不按顺序解析每个链接
至于 Akka,我只是不能在这里使用演员,所以只能使用 Future 或 Par*
【问题讨论】:
-
当我在
ParIterableLike类中查看map函数的实现时,上面写着...tasksupport.executeAndWaitResult...。我不了解所有细节,但这可能意味着该线程已经被此实现阻塞。使用Futures的另一种方法是flatMap而不是map,将单个Futures组合成一个Future,当所有“小”Futures 都准备好时,该Future就准备好了。我不能肯定地说,因为我也在学习 scala,提出了同样的问题。 ;) 祝你好运。
标签: parsing scala concurrency parallel-processing concurrent-programming