Каков наилучший подход к составлению графика Callables, который может истечь в ситуации опроса? - PullRequest
0 голосов
/ 21 мая 2009

У меня есть несколько Callables, которые запрашивают некоторые JMX Beans, поэтому у каждого из них может быть время ожидания. Я хочу опросить значения, скажем, каждую секунду. Наиболее наивным подходом было бы начинать каждый в отдельном потоке, но я хочу минимизировать количество потоков. Какие варианты я должен сделать это лучше?

Ответы [ 3 ]

1 голос
/ 23 мая 2009

Моя интерпретация заключается в том, что у вас есть куча вызываемых объектов, которые нужно опрашивать через некоторый интервал. Проблема, если вы используете пул потоков, состоит в том, что пул будет загрязнен самыми медленными членами, а ваши более быстрые будут голодать.

Похоже, у вас есть контроль над расписанием, так что вы можете рассмотреть экспоненциальный подход отсрочки. То есть после того, как Callable X запустился (и, возможно, по тайм-ауту), вы подождите 2 секунды вместо 1 секунды, прежде чем его перепланировать. Если это не помогло, перейдите к 4 с, затем к 8 и т. Д. Если вы используете ScheduledThreadPoolExecutor , он поставляется со встроенным способом сделать это, позволяя вам планировать свои исполнения после заданной задержки.

Если вы установите постоянное время ожидания, эта стратегия уменьшит восприимчивость вашего пула к монополизации медленными. Очень трудно полностью избавиться от этой проблемы. Использование отдельного потока для каждого запрашиваемого объекта - действительно единственный способ убедиться, что вы не получите голодание, и это может быть очень ресурсоемким, как вы говорите.

Другая стратегия состоит в том, чтобы объединить ваш пул в быстрый и медленный. Если у объекта истекает время (скажем, более чем в N раз), вы перемещаете его в медленный пул. Это позволяет быстро поддерживать ваш быстрый пул, и хотя медленные все мешают друг другу, по крайней мере они не забивают быстрый пул. Если они какое-то время имеют хорошую статистику, вы можете снова повысить их до быстрого пула.

0 голосов
/ 04 июня 2009

я согласен с robbotic ... реализация cachedThreadPool решит вашу проблему, так как ограничит количество потоков до оптимального уровня, в то же время есть тайм-ауты, которые освободят ваши неиспользуемые ресурсы

0 голосов
/ 04 июня 2009

Как только вы submit a Callable, вы получите Future - указатель на будущий результат. Вы можете решить подождать его завершения в течение заданного промежутка времени:

Future<String> future = executorService.submit(callable);
try {
  future.get(1, TimeUnit.SECONDS);
} catch ( TimeoutException e ) {
  future.cancel(true);
} catch ...

Вызов get с тайм-аутом позволяет получить исключение, если задача не была выполнена. Это не различает не запущенные задачи и запущенные, но не завершенные. С другой стороны, cancel примет логический параметр mayStopIfRunning, поэтому вы можете выбрать, например, отменять только те задачи, которые еще не запланированы.

...