Grails CSV插件-并发

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

我在我的应用程序中使用的插件是:GrailsCSV插件Grails2.5.3。 我需要实现并发功能,例如:GPars,但我不知道如何实现

现在,配置是顺序处理。我的代码片段示例:


谢谢。

在这种情况下实现并发可能不会给您带来多少好处。这实际上取决于瓶颈在哪里。例如,如果瓶颈在于读取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()}`必须等待整个列表处理完毕,然后才能继续下一步。