While writing a skeleton program for ExecutorService invokeAll
I came across an interesting scenario which seems created a deadlock. Couldn't figure out exactly why this is happening.
Here is the program which instantiates 3 tasks and calls invokeAll()
int poolSize = Runtime.getRuntime().availableProcessors();
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
Set<Callable<Object>> tasksSet = new HashSet<>();
tasksSet.add(new Task1());
tasksSet.add(new Task2());
tasksSet.add(new Task3());
List<Future<Object>> resultSet = pool.invokeAll(tasksSet);
for (Future<Object> future : resultSet) {
Object result;
try {
result = future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
ex.printStackTrace();
Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
ex.printStackTrace();
Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex);
} catch (TimeoutException ex) {
ex.printStackTrace();
Logger.getLogger(CallableDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
pool.shutdown();
And Task1
code:
public class Task1 implements Callable<Object> {
@Override
public Object call() throws Exception {
long val = 0;
for (long i = 0; i < Long.MAX_VALUE - 5000; i++) {
val += i;
}
return "Sucessfull Task1 object...";
}
}
Task2
and Task3
code also same except these two classes use Integer.MAX_VALUE
in for loop check.
When I run this program it stuck forever and interestingly other two tasks also didn't run. My machine has is 8-core processor. Any thoughts why this behavior?
If I change Long.MAX_VALUE to Integer.MAX_VALUE, everything works fine.
Another interesting observation is:
Instead of calling invokeAll()
, if submit()
these tasks individually, two other tasks completed on time except Task1 (which has Long.MAX_VALUE).