Я не уверен, что правильно понял вопрос, но, похоже, вам нужен Semaphore
для каждого ключа API.
Semaphore key1Semaphore = new Semaphore(2);
Semaphore key2Semaphore = new Semaphore(3);
Вы можете проверить, есть ли у key1Semaphore
разрешения, и получить их, если они доступны, позвонив по номеру key1Semaphore.tryAcquire()
. Это неблокирующая функция, поэтому, если она завершится с ошибкой и вернет false, вы можете попытаться получить семафор из другого ключа API и отправить задачу из этого.
Важно, чтобы в конце задачи с использованием одного из ключей API разрешение семафора возвращалось обратно.
Вам может потребоваться дополнительный объект для синхронизации с wait()
и notify()
, чтобы после завершения задачи он уведомлял основной поток, который отправляет задачи, чтобы снова проверить семафоры.
По сути, вы получаете то, что ваш диспетчер задач отправит 5 задач вашим ExecutorService
из 3 рабочих, и затем он не сможет отправлять больше, пока не будет выпущено одно из разрешений семафора.
Когда задача завершается и разрешение высвобождается, диспетчер получает уведомление, поэтому он разблокируется от ожидания и снова проверяет семафоры по порядку и отправляет задачи в ExecutorService
.
Это решение немного смещено в сторону первых ключей API, но вы можете уточнить его еще больше, проверив длину задач для каждого ключа и распределив их более справедливо. Вы можете даже повернуть индекс, чтобы при каждом цикле индекс увеличивался на 1, чтобы при первом запуске с API KEY 1, а при втором - с API KEY 2 и т. Д.