I have submitted a task using executors and I need it to stop after some time (e.g. 5 minutes). I have tried doing like this:
for (Future<?> fut : e.invokeAll(tasks, 300, TimeUnit.SECONDS)) {
try {
fut.get();
} catch (CancellationException ex) {
fut.cancel(true);
tasks.clear();
} catch(ExecutionException ex){
ex.printStackTrace(); //FIXME: gestita con printstack
}
}
But I always get an error: I have a shared Vector that needs to be modified by the tasks and then read by a thread, and even if I stop all the task, if the timeout occurs I get:
Exception in thread "Thread-1" java.util.ConcurrentModificationException
Is there something wrong? How can I stop the tasks submitted that are still working after 5 minutes?
Best Answer
Just because you call
cancel()
onFuture
doesn't mean that the task will stop automatically. You have to do some work within the task to make sure that it will stop:cancel(true)
so that an interrupt is sent to the task.InterruptedException
. If a function in your task throws anInterruptedException
, make sure you exit gracefully as soon as possible upon catching the exception.Thread.currentThread().isInterrupted()
if the task does continuous computation.For example:
Also, as other posts have mentioned:
ConcurrentModificationException
can be thrown even if using the thread-safeVector
class, because iterators you obtain fromVector
are not thread-safe, and thus need to be synchronized. The enhanced for-loop uses iterators, so watch out: