【发布时间】:2012-08-18 19:00:01
【问题描述】:
我有一个多线程程序,它似乎并没有真正利用我机器上的所有内核。这是代码,任何输入都将受到高度赞赏。
主类
public class MainClass{
public static void main(String [] args){
Work work=new Work();
work.doIt();
}
}
第二个类创建任务并交给ExecutorService,这里是伪代码
public class Work{
public void doIt() throws InterrputedException, Exception{
map=get some data and put it in the map;
ArrayList<Future<Integer>> list=new ArrayList<Future<Integer>>();
ArrayList<WorkCallable>jobs=new ArrayList<WorkCallable>();
for each entry in the map;
jobs.add(new WorkCallable(entry);
int numCores=Runtime.getRuntime().availableProcessors();
ExecutorService executor=Executors.newFixedThreadPool(numCores);
int size=jobs.size();
for(int i=0;i<size;i++){
Callable<Integer> worker=jobs.get(i);
Future<Integer> submit=executor.submit(worker);
list.add(submit);
}
executor.shutdown();
while(!executor.isTerminated()) {}
do something with the returned data;
}
}
可调用类
public class WorkCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception{
Properties props=new Properties();
props.put("annotators", "tokenize, ssplit, pos");
StanfordCoreNLP pipeline=new StanfordCoreNLP(props);
for(String id:entry.keySet()){
Annotation document=new Annotation(entry.get(id));
pipeline.annotate(document);
process the data;
return an integer value;
}
}
问题是,当我检查有多少线程正在运行时,我发现只有很少,而且执行器似乎没有利用理想的内核!
我希望描述清楚。
更新:
- 使用的库是 StanfordCoreNLP 包,用于处理作为 documentID 及其内容的 Map 传递给 Callable 对象的文本。处理数据不是问题,因为我在不包含 StanfordCoreNLP 库的情况下工作得很好。换句话说,文档的浅层处理可以正常工作并利用所有内核。但是当我包含这个包时它没有。
【问题讨论】:
-
您忙于等待
while(!executor.isTerminated()) {}需要一个核心。你不应该那样做。有awaitTermination供您使用。顺便说一句,“非常少”的数量究竟是多少,你知道你拥有多少个核心?更好的是,System.out.println(Runtime.getRuntime().availableProcessors())打印什么? -
描述也不是很清楚。 “加载一些库”和“处理数据”听起来都像是潜在的同步操作,这可能会导致所有线程退出运行状态,但只有一个线程处于运行状态。
-
感谢您的 cmets Marko 和 mazaneicha。我同意加载库可能是个问题。
标签: java multithreading nlp executorservice stanford-nlp