Java ScheduledThreadPool для использования дополнительных потоков, если продолжительность задачи превышает период

Итак, скажем, у меня есть ScheduledExecutorService с 10 потоками, сгенерированными как таковые, и я запускаю периодическую задачу, которая запускается раз в минуту.

svc = Executors.newScheduledThreadPool(10);
svc.scheduleAtFixedRate(myRunnable, 0, 1, TimeUnit.MINUTES);

Это идеальный способ заставить myRunnable запускаться раз в минуту. Теперь предположим, что выполнение myRunnable занимает больше минуты (поэтому продолжительность задачи теперь превышает период задачи). Текущее поведение, которое я заметил, заключается в том, что пул потоков будет ждать, пока myRunnable не завершит выполнение, прежде чем снова запуститься. Похоже, что я говорю своим кодом, чтобы запланировать задачу, но занять только один поток в пуле с myRunnable.

Есть ли вариант/другой вызов API/дополнительного метода, где я могу заставить этот пул потоков просто захватить следующий доступный поток и запустить его, если первый поток не завершил выполнение за одну минуту? (Или я делаю это неправильно?)


person Michael Plautz    schedule 30.10.2014    source источник
comment
Это предполагаемое поведение: Из JavaDoc для scheduleAtFixedRate: Если какое-либо выполнение этой задачи занимает больше времени, чем ее период, то последующие выполнения могут начаться с опозданием, но не будут выполняться одновременно.   -  person Powerlord    schedule 30.10.2014
comment
Не могу поверить, что пропустил это, спасибо. Я прочитал JavaDoc для Executors.newScheduledThreadPool и ничего не увидел, но я забыл проверить сам scheduleAtFixedRate JavaDoc.   -  person Michael Plautz    schedule 30.10.2014


Ответы (1)


Почему бы не запланировать свой Runnable на однократное выполнение (после задержки), а затем в начале вашего Runnable запланировать его снова?

person Alvin Thompson    schedule 30.10.2014
comment
Это определенно выполнит то, что я пытаюсь сделать, если я помещу его в начало моего Runnable, при условии, что я могу гарантировать, что мой Runnable, по крайней мере, всегда будет вызываться (что я не могу представить себе в ситуации, когда он не по крайней мере вызывается, даже если за ним за ним следует исключение). Мне было интересно, было ли что-то встроено в API для этого, но, похоже, это не так. - person Michael Plautz; 30.10.2014
comment
@MichaelPlautz Это предложение приведет к тому, что задача будет выполняться с немного изменяющимся периодом, который немного превышает одну минуту. Если это приемлемо, то вперед. Но если вам нужно, чтобы задача запускалась с точным интервалом в одну минуту, подумайте о том, чтобы запланировать периодическую задачу, которая запускается раз в минуту и ​​ничего не делает, кроме как запланировать однократное немедленное выполнение реальной задачи. - person Solomon Slow; 30.10.2014
comment
Обратите внимание, что перепланирование самой задачи может привести к одновременному доступу к задаче нескольких потоков, если выполнение задачи перекрывается, как описано в вопросе. Поэтому убедитесь, что он либо не имеет состояния, либо реализован потокобезопасным способом! (Возможно, это одна из причин, почему такой встроенной функции нет) - person isnot2bad; 31.10.2014