Grails CSV插件-并发
我在我的应用程序中使用的插件是:GrailsCSV插件Grails2.5.3。 我需要实现并发功能,例如:GPars,但我不知道如何实现 现在,配置是顺序处理。我的代码片段示例:Grails CSV插件-并发,grails,grails-plugin,grails-2.0,grails-controller,gpars,Grails,Grails Plugin,Grails 2.0,Grails Controller,Gpars,我在我的应用程序中使用的插件是:GrailsCSV插件Grails2.5.3。 我需要实现并发功能,例如:GPars,但我不知道如何实现 现在,配置是顺序处理。我的代码片段示例: 谢谢。在这种情况下实现并发可能不会给您带来多少好处。这实际上取决于瓶颈在哪里。例如,如果瓶颈在于读取CSV文件,那么就没有什么优势,因为只能按顺序读取文件。有了这些,下面是我能想到的最简单的例子: import groovyx.gpars.GParsPool def tokens = csvFileLoad.inpu
谢谢。在这种情况下实现并发可能不会给您带来多少好处。这实际上取决于瓶颈在哪里。例如,如果瓶颈在于读取CSV文件,那么就没有什么优势,因为只能按顺序读取文件。有了这些,下面是我能想到的最简单的例子:
import groovyx.gpars.GParsPool
def tokens = csvFileLoad.inputStream.toCsvReader(['separatorChar': ';', 'charset': 'UTF-8', 'skipLines': 1]).readAll()
def failedSaves = GParsPool.withPool {
tokens.parallel
.map { it[0].trim() }
.filter { !Department.findByName(it) }
.map { new Department(name: it) }
.map { customImportService.saveRecordCSVDepartment(it) }
.map { it ? 0 : 1 }
.sum()
}
if(failedSaves > 0) transactionStatus.setRollbackOnly()
如您所见,首先读取整个文件;因此,这是主要的瓶颈。大多数处理与map()
、filter()
和sum()方法同时进行。最后,如果任何部门
未能保存,事务将回滚
注意:我选择使用map()
-sum()
对,而不是使用anyParallel()
。为了避免将map()
生成的并行数组转换为常规Groovy集合,请执行anyParallel()
,它创建一个并行数组,然后将其转换回Groovy集合
改进
正如我在示例中已经提到的,在并发执行开始之前,首先完全读取CSV文件。它还尝试保存所有部门
实例,即使其中一个未能保存。您可能想要(这就是您演示的)或不想要。好的,谢谢。我没有复制所有代码,只有主要部分。我将用这个例子来尝试。PD:当一行失败时,执行就会停止,只执行SetRollback。每个并行、collectParallel和anyParallel之间有什么区别?它们是Groovy的每个、collect和any的并发等价物。好的,让我详细说明一下。让我们采用方法collect()
,collectpallel()
和map()
。这些方法中的每一个都做同样的事情:它为列表中的每个项执行闭包,并根据闭包的返回值构建一个新列表。区别在于collect()
按顺序遍历列表collectParallel()
分解列表并(间接)将其交给线程,然后将列表重新连接在一起,使其看起来像collect()
的输出map()
与collectParallel()
类似,只是它不执行连接步骤……例如,map{it[0].trim()}
能够执行闭包并立即将结果传递到下一步,而无需等待处理整个列表。另一方面,`collectParallel{it[0].trim()}`必须等待整个列表处理完毕,然后才能继续下一步。