I want a Thread-Pool that provides a maximum of X Threads to process tasks, so far no problem. However each submitted Task can specify an IO-Target which is specifically limited (say Y).
So a submitted IOTask returns the target "google.com" with limit 4 (Y) and the pool has a global limit 16 (X). I want to submit 10 google.com-tasks where only 4 are processed in parallel and the pool has 12 threads free for other tasks.
How can I achieve this?
Implementing this functionality is not simple since you will either need to have separate queues per target (so the waiting code becomes far more complicated), or one queue from which you then skip over targets that are at capacity (incurring a performance overhead). You can try to extend ExecutorService to achieve this, but the extension appears to be non-trivial.
Updated answer / solution:
After thinking about this a little bit more, the easiest solution to the blocking problem is to have both a blocking queue (as per normal) as well as a map of queues (one queue per target, as well as a count of available threads per target). The map of queues is used only for tasks that have been passed over for execution (due to too many threads already running for that target) after the task is fetched from the regular blocking queue.
So the execution flow would look like this:
if the available count > 0
when a thread finishes execution of a task it:
This solution avoids any significant performance overhead or having a separate thread just to manage the queue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With