如何在“池”线程中拆分一系列值?

时间:2015-02-26 10:47:29

标签: arrays multithreading coldfusion

我有一些处理大约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)相等的子数组。考虑到我有范围的开始,范围的结束,以及我希望将其划分的线程数,是不是有更简单的方法来分解它并将其分配给线程?

1 个答案:

答案 0 :(得分:3)

(来自评论..)

如果你已经有一个阵列,为什么要再次循环呢?没有内置函数,但由于数组是java List,因此简单的yourArray.subList(startIndex, endIndex)就可以了。显然,如果记录数小于处理线程数,则添加一些错误处理。

NB:由于它是一个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>