2009-05-21 6 views
0

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

ответ

1

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

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

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

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

0

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

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

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

0

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