ExecutorService with a fixed sized thread pool - how to block any more tasks being added until the pool size has space

Viewed 99

My current implementation counts how many tasks are added to the pool and decrements when the complete their task.

I then tell the main code to repeat + sleep until the active tasks drop below the thread pool size before I add another task.

I feel there must be a better way?

I do not want the tasks placed in a queue, but I would happily wait for the pool to tell me it’s ready to receive more tasks.

For background, I have a web-service that I wish to invoke and it involves around 150,000 HTTP calls, I plan to do 50 at a time until the full 150,000 calls have been completed, this is why I can’t queue all tasks as I will exhaust my RAM.

I do not want any blocking to be on a timeout - I’m happy to wait as long as necessary for the thread pool to have space for new tasks.

Any suggestions on how this can be achieved?

1 Answers

One method to handle this is to startup your own consumer threads that run against your own BlockingQueue, avoiding the use of an ExecutorService altogether. I.e. declare an ArrayBlockingQueue with capacity of 50 and have a producer thread offering/putting elements to it (which will block when the queue is full) and the consumer threads pulling from it and doing the necessary work.

Alternatively there is an implementation of ThreadPoolExecutor which does what you want by adding a custom RejectedTaskHandler to adding blocking behavior to the execute call. See NotifyingBlockingThreadPoolExecutor on github. I can't vouch for its quality but it should do exactly what you need.

Related