我有一些代码可以处理大约30,000条记录。基本轮廓是这样的:
startRecordID = 2345;
endRecordID = 32345;
for(recordID=startRecordID; recordID <= endRecordID; recordID++){
// process record...
}
现在,此处理需要很长时间,我想拥有一个由15个线程组成的线程池,并为每个线程提供要处理的recordID列表,然后最后将它们全部加入。
在过去,我是用类似以下代码的代码完成此操作的,其中
recordLists
是一个子数组数组,每个子数组包含要处理的记录的1/15:<cfset numThreads = 15 />
<!--- keep a running list of threads so we can join them all at the end --->
<cfset threadlist = "" />
<cfloop from="1" to="#numThreads#" index="threadNum">
<cfset threadName = "recordProcessing_#threadNum#" />
<cfset threadlist = listAppend(threadlist, threadName) />
<cfthread action="run" name="#threadName#" recordList="#recordList[threadNum]#">
<cfloop from="1" to="#ArrayLen(recordList)#" index="recordIndex">
<cfset recordID = recordList[recordIndex] />
... process recordID ...
</cfloop>
</cfthread>
</cfloop>
<!--- Join all threads before continuing --->
<cfthread action="join" name="#threadlist#" timeout="4000"/>
这很好用(尽管我也可以将旧代码转换为cfscript :)),但是创建子数组的recordLists数组并不是那么简单...我可以想到的方法是循环遍历将startRecordID-endRecordID中的数字添加到数组中,然后在其上运行ArrayDivide函数(我们已经在代码库中定义了该函数),以将其拆分为numThreads(在这种情况下为15个)相等的子数组。考虑到我具有范围的开始,范围的结束以及要在其中划分的线程数,是否有更简单的方法可以将其分解并分配给线程?
最佳答案
(来自评论..)
如果您已经有了一个数组,为什么还要再次遍历它呢?没有内置函数,但是由于数组是java List
,因此简单的 yourArray.subList(startIndex, endIndex)
就可以解决问题。显然,如果记录数少于处理线程数,则添加一些错误处理。
注意:由于它是一种Java方法,因此索引从零(0)开始,并且endIndex
是排他的。而且,在大多数方面,结果都类似于CF阵列。但是,它是不可变的,即无法修改。
<cfscript>
// calculate how many records to process in each batch
numOfIterations = 15;
totalRecords = arrayLen(recordsArray);
batchSize = ceiling(totalRecords/numOfIterations);
for (t=0; t < numOfIterations; t++) {
// calculate sub array positions
startAt = t * batchSize;
endAt = Min(startAt+batchSize, totalRecords);
// get next batch of records
subArray = recordsArray.subList(startAt, endAt);
// kick off a thread and do whatever you want with the array ...
WriteOutput("<br>Batch ["& t &"] startAt="& startAt &" endAt="& endAt);
}
</cfscript>
关于arrays - 如何在 “pool”线程之间划分值范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28740376/