Problem Definiton:-
I need to insert some values into Database as soon as all the tasks of ExecutorService have finished exectuing there jobs. In other words, I can insert into database only when all the tasks have finished executing there jobs as the things that I need to insert into db, is dependent on all the threads finishing there tasks..
So how I can check whether all the tasks of ExecutorService have been finished executing and then start inserting into database.
Below is the code in which I am creating task using ThreadPoolExecutor.
executorService = new ThreadPoolExecutor(
noOfThreads,
noOfThreads,
500L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(noOfThreads),
new ThreadPoolExecutor.CallerRunsPolicy()
);
// Running for particular duration of time
while(System.currentTimeMillis() <= endTime) {
Command newCommand = getNextCommand();
Task nextRunnable = new Task(newCommand, existId, newId);
executorService.submit(nextRunnable); // Submit it for execution
}
/*
Previously I was inserting into database here, but it was wrong as it might be
possible that some threads are still in progress. And If I am inserting right here
into database, then some information I will be loosing for sure. So how can I check
whether all the tasks have finished executing and then I can insert into database.
*/
executorService.shutdown();
if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS)) {
executorService.shutdownNow();
}
The code that I will be using for insertion is below-
// Inserting into Database when all the task have finished executing, currently I
for (Entry<Integer, LinkedHashMap<Integer, String>> entry : GUID_ID_MAPPING.entrySet()) {
pstatement = db_connection.prepareStatement(LnPConstants.UPSERT_SQL);
pstatement.setInt(1, entry.getKey());
pstatement.setString(2, entry.getValue().get(LnPConstants.CGUID_ID));
pstatement.setString(3, entry.getValue().get(LnPConstants.PGUID_ID));
pstatement.executeUpdate();
}
So I need to put this for loop somewhere after all the tasks have finished executing.
Update:-
So Something like this-
executorService.shutdown();
if (!executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS)) {
executorService.shutdownNow();
}
// Now Insert into Database when all the task have finished executing
for (Entry<Integer, LinkedHashMap<Integer, String>> entry : GUID_ID_MAPPING.entrySet()) {
pstatement = db_connection.prepareStatement(PDSLnPConstants.UPSERT_SQL);
pstatement.setInt(1, entry.getKey());
pstatement.setString(2, entry.getValue().get(PDSLnPConstants.CGUID_ID));
pstatement.setString(3, entry.getValue().get(PDSLnPConstants.PGUID_ID));
pstatement.executeUpdate();
}
You basically have the answer already. Wait for
executorService.awaitTerminationto return, and the executor will have completed all it’s tasks.This ignores tasks that may have failed due to an error. Another way to do this, and to check for errors is to do something like,
Another class to look at is ExecutorCompletionService. ExecutorCompletionService allows you to get tasks in the order that they actually complete.