Это будет трудно сделать это путем мониторинга центрального процессора, используемого текущим процессом. Эти цифры, как правило, отстают от реальности, и результат в большей степени будет пиками и долинами. Проблема в том, что ваши потоки в основном блокируются IO, и нет никакого хорошего способа предвидеть, когда байты будут доступны для чтения в ближайшем будущем.
При этом вы можете начать с ThreadPoolExecutor
при определенном максимальном количестве потоков (для одного процессора, скажем, 4), а затем проверить каждые 10 секунд или около того среднее значение нагрузки. Если среднее значение нагрузки ниже того, что вы хотите, вы можете позвонить setMaximumPoolSize(...)
с большим значением, чтобы увеличить его в течение следующих 10 секунд. Возможно, вам потребуется опросить 30 и более секунд между каждым расчетом, чтобы сгладить производительность вашего приложения.
Чтобы отслеживать общее время процессора для всех потоков, вы можете использовать следующий код. Не уверен, что это лучший способ сделать это
long total = 0;
for (long id : threadMxBean.getAllThreadIds()) {
long cpuTime = threadMxBean.getThreadCpuTime(id);
if (cpuTime > 0) {
total += cpuTime;
}
}
// since is in nano-seconds
long currentCpuMillis = total/1000000;
Вместо того, чтобы пытаться максимизировать уровень процессора для вашего паука, вы можете рассмотреть вопрос о попытке максимизировать пропускную способность. Возьмите образец количества страниц, разбросанных за единицу времени, и увеличьте или уменьшите максимальное количество потоков в ExecutorService
до тех пор, пока это не будет максимизировано.
Одна вещь, которую следует учитывать, - использовать NIO и селекторов, чтобы ваши потоки всегда были заняты, а не всегда ожидали ввода-вывода. Вот good example tutorial about NIO/Selectors. Вы также можете использовать Pyronet, который, как представляется, предоставляет некоторые полезные функции вокруг NIO.
Я думаю, что вы на правильном пути. Следует рассмотреть возможность использования NIO и селекторов, чтобы ваши потоки всегда были заняты, а не всегда ожидали ввода-вывода.Трудно максимизировать пропускную способность, не имея пиков и долин в противном случае. – Gray
Там, Серый избил меня к ней :) С блокировкой ввода-вывода вам понадобится смехотворно большое количество потоков, которые будут тратить оперативную память и больше ничего не делать, кроме как ждать. –
Возможно, вам не захочется создавать темы самостоятельно. Используйте «ExecutorService», который повторно использует потоки для задач «Runnable» или «Callable» и уменьшает накладные расходы на создание разрушающих потоков. –