With the following code snippet. Can I make the assumption that all threads have completed once I get to populate the List? Or could it be a case where a thread is still running once I start adding elements to the list?
Sven: Can I make the assumption that all threads have completed once I get to populate the List?
Actually, the line:
ensures that all the tasks that you submitted would have completed. The reason being, get() waits for task completion. So, there is no way(apart from throwing an exception like InterruptedException/CancellationException) that get() call can return without task completion. Since this line is executed only after the other 3 have finished and your executor is a local variable(hope it does not escape the method) so you can safely assume that all tasks have finished execution.
Just FYI, calling shutdown does not guarantee that all tasks have finished execution when the method returns.
Yes, you will gain some performance, because you won't have to wait for all the tasks to be done before adding them to the list (and/or doing whatever other work you need done with the results). By using the take() method you know you have a finished value, you can add it to the list, do your work then come back to the CompletionService when you are ready for the next one while the other tasks are still executing and finishing up.
If all you are doing is adding to the list and you need all of them finished before you move on then the amount of saved time will be tiny unless you have many concurrent activities.