关于用多线程时任务分配与结果收集的问题的设计讨论 (一)

2014-11-24 01:40:06 · 作者: · 浏览: 0

假定任务是这样的: 对于给定字符串,如“threadTest”, 给它再续上个“@”, 最后返回结果。 这些单条任务间没有任何的依赖关系。

假定这样的字符串很多, 如1000个, 而可以创建的线程数不能多于35个。

于是, 就有了线程创建后, 分配任务的问题, 怎么能在代码上优雅地把给定任务组,分配到线程池中, 然后再去收集这些线程处理后的结果?

想用java.util.concurrency中的Future, 可这个好像不能支持批量结果的收集吧?

于是, 用线程很原始地写了个粗暴分配任务与收集结果的代码, 这个很丑陋的。 大家说怎么改进,设计?

========下面是我粗陋实现的代码===========

Java代码
package rmn.thread;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TaskAssignAndResultCollection {
private final static int DEFAULT_THREAD_NUM = 5;

private int threadNum = DEFAULT_THREAD_NUM;
private Worker[] threads = null;

public TaskAssignAndResultCollection(int threadNum) {
super();
if (threadNum == 0) {
threadNum = DEFAULT_THREAD_NUM;
} else {
this.threadNum = threadNum;
}

}

public Map processStringBatchly(
String[] datas) {

if (threads == null) {
synchronized (this) {
threads = new Worker[threadNum];

for(int i = 0 ; i < threadNum; i++) {
threads[i] = new Worker();
}
}
}

// 怎么把domainName分配给线程, 让它们自己运行去?平均分配,
int domainSize = datas.length;
int domainNamePerThread = domainSize / threadNum;
int leftDomainName = domainSize % threadNum;

List listDomainName = Arrays.asList(datas);

//先每个线程平均地分domainNamePerThread个DomainName,
int endIndex = 0;
for (int i=0; i int beginIndex = i * domainNamePerThread;
int step = domainNamePerThread;
endIndex = beginIndex + step;
List subDomainNames = new ArrayList(listDomainName.subList(beginIndex, endIndex));

threads[i].setDomainNameList(subDomainNames);
}

//然后,再把剩下的逐个分配。
for(int i=0; i< leftDomainName; i++) {
threads[i].addDomainName(listDomainName.get(endIndex + i));
}

for(Worker thread : threads ) {
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Map totalResult = new HashMap();

for(Worker thread : threads) {
totalResult.putAll(thread.getResultCollector());
}

return totalResult;
}


public static void main(String[] args) {
String[] datas = new String[] {"baidu.com", "sohu.com", "163.com", "iteye.com"};

TaskAssignAndResultCollection c = new TaskAssignAndResultCollection(3);

Map resultCollector = c.processStringBatchly(datas);
c.showMsg(resultCollector);
}

private void showMsg(Map result) {
for(Map.Entry me : result.entrySet()) {
String data = me.getKey();
String r = me.getValue();

String msg = "原始值[" + data + "]" + " 处理后[" + r + "]" ;

System.out.println(msg);
}
}



}

class Worker extends Thre