Reputation: 2644
I'm working on a project where there is a large input of data elements that need to be processed. The processing of each is independent of the others and I need a return a result from each. What I'm doing now is creating a Callable
task for each element to do the processing and using ExecutorCompletionService
to collect the Future
result as the threads complete.
I then have another thread that is pulling the Future
objects from the ExecutorCompletionService
queue. This thread just spins in an infinite while loop and calls take()
which blocks until a Future
shows up in the queue.
What I'm trying to do is avoid the scenario where the queue of Future
objects grows faster than I pull them off the queue so I'd like to sleep the process that's creating tasks if I get behind on processing the Future
results.
The problem I'm running into is that I'm not able to find a way to see how many Future
objects are in the ExecutorCompletionService
queue. Is there a way to do this?
I could probably keep an external counter that I increment when a new task is created and decrement when a Future
is processed but this only gets me to the number of outstanding tasks, not the number that are actually done. Any thoughts on the best way to tackle this?
Upvotes: 1
Views: 806
Reputation: 78
You can pass the queues an executor uses using one of the overloaded constructor. Since queue implements Collection you could just call .size() on that queue. You will have a queue for the completion and another queue for the executor that the ExecutorCompletionService uses so you could tell how many are submitted and how many are completed between those two.
You'll just need to hold on to those queues after you create them and pass it to whatever is watching the size of them.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorCompletionService.html shows the overloaded constructor
Upvotes: 1