2013-03-27 5 views
0

Для нашего проекта по разработке сетевого стресс-теста мы наводняем пакеты на целые подсети. У нас есть класс Runnable, который принимает порт и широковещательный адрес, а через некоторое время (! Thread.currentThread() isInterrupted) он отправляет определенный пакет. Затем у нас есть основной класс, который выполняет итерацию через каждый сетевой интерфейс и каждый возможный порт и добавляет класс Runnable в ExecutorService с фиксированным пулом 1000 потоков. Проблема в том, что если ExecutorService ожидает, что текущие 1000 потоков завершат обработку, они никогда не будут, так как они находятся в цикле while. Однако запуск каждого отдельного потока (65536 * количество интерфейсов) занимал бы слишком много памяти. Мы ищем способ циклического переключения потоков, чтобы все они имели возможность работать в течение некоторого времени и сохраняли память, сохраняя при этом высокий сетевой выход.Как проехать по многим потокам в Java

+3

Вы злитесь? – pamphlet

+0

Я не думаю, что хотел бы внести свой вклад в это усилие. – Randy

ответ

0

Я думаю, вы можете страдать от заблуждения, что больше потоков всегда дает более высокую пропускную способность. Это часто бывает не так.

Ваше приложение, вероятно, будет связано с ЦП или связано пропускной способностью сетевой карты. Заставляя ОС жонглировать десятками тысяч потоков, конкурирующих за эти ресурсы, не собирается увеличить вашу пропускную способность. Большое количество потоков помогает только в том случае, когда потоки тратят большую часть своей жизни, ожидая некоторого высокопроизводительного внешнего ресурса (например, базы данных). Поскольку вы просто взрываете пакеты и (предположительно) не интересуетесь никакими ответами, нет естественной точки ожидания.

Я бы порекомендовал вам иметь столько потоков, сколько у вас есть процессоры и/или сетевые карты (в зависимости от того, что меньше).

+0

Значит, это будет работать так же, как использовать один поток? Я думал, что больше потоков будет быстрее, потому что, когда я создал программу сканирования портов, которая имела период ожидания на порт, несколько потоков ускорили программу значительно. – Samuel

+0

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

+1

Используете ли вы TCP-пакеты или одноадресную рассылку? Если вы ожидаете ACK, несколько потоков принесут некоторую пользу. Но только до предела. Они очень быстро пойдут друг на друга. Попробуйте цифры, такие как 1, 5, 10, 50 и найдите сладкое пятно. – pamphlet

0

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

Например, если каждая задача имеет 1000 шагов для выполнения нескольких раз: - Задача 1 пробеги шагов 1-100, а затем заканчивает добавление себя обратно в очередь исполнителя для этапов 101-200 - Задача 2 получает шанс выполнить (и закончить) аналогично - Задача 1 теперь следующая в очереди, поэтому она выполняет 101-200, а затем добавляет обратно в очередь исполнителя на 201-300. - и т. Д. До тех пор, пока задача 1 не достигнет конца - 901-1000 - тогда, если она хочет продолжить выполнение, снова возвращается на 1-100.

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

Смежные вопросы