I have very similar multithreaded code elsewhere in my codebase that works fine, but I can’t see quite what’s going wrong here.
This is a simple multi-threaded process to generate some result XML for a search query. The output of running this method is:
Returning from threads
The line System.out.println(“Finished multithreading loop”);” is never reached.
Modifying the number of threads doesn’t help.
private void fillAllResults() {
int threads = 2;
final FutureTask[] tasks = new FutureTask[threads];
final ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < allResults.size(); i++) {
tasks[i] = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
int index;
while ((index = getResultsIndex()) < allResults.size()) {
System.out.println("Processing result " + index);
Result result = allResults.get(index);
fillResultXML(result);
}
System.out.println("Returning from threads");
return 1;
}
});
executor.execute(tasks[i]);
}
for (int i = 0; i < threads; i++) {
try {
tasks[i].get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
System.out.println("Finished multithreading loop");
}
Edit, thanks all for the quick replies! Here’s the answers:
It shows ‘processing result’ as many times as I have results. If allResults.size() is 25, it shows processing result 1, processing result 2 … processing result 24.
Here’s the extra code that’s missing:
private List<Result> allResults = new ArrayList<Result>();
private int resultsIndex = 0;
private synchronized int getResultsIndex() {
return resultsIndex++;
}
And in case anyone’s wondering, I can guarantee that none of the code within the loop increases the size of allResults.
I suppose it is related to the fact, that your array
taskshas a length ofthreads(i.e. two in your case) but you assign more values to it within the linesIf your list
allResultshas more than two entries your thread will be stopped by anArrayIndexOutOfBoundsException. Maybe you catch this one but do not handle it properly outside the code you presented.