У меня есть многопоточная программа, которая, похоже, не использует все ядра на моей машине. Вот код, и любой вклад будет высоко оценен.
Основной класс
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 для обработки текста, передаваемого объекту Callable, в виде карты идентификатора документа и его содержимого. Обработка данных не является проблемой, так как у меня все отлично работает без включения библиотеки StanfordCoreNLP. Другими словами, неглубокая обработка документов работает нормально и использует все ядра. Но когда я включаю этот пакет, это не так.
while(!executor.isTerminated()) {}
тут же занимает одно ядро. Вы не должны этого делать. Для ваших целей естьawaitTermination
. Кстати, какое именно количество очень мало и сколько ядер вы знаете за тот факт, что у вас есть? А еще лучше, что печатаетSystem.out.println(Runtime.getRuntime().availableProcessors())
? - person Marko Topolnik   schedule 18.08.2012