Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > максимальное кол-во потоков (соединений)


Автор: CSharpProgrammer 20.6.2012, 22:39
Доброго времени суток.

Задача такая, многопоточная закачка файлов из интернета (один пото - один файл). Так вот собственно интересует как можно проверить максимальное кол-во потоков (соединений), которое можно установить не в ущерб производительности?

Автор: Vasay 21.6.2012, 01:32
Цитата(CSharpProgrammer @  20.6.2012,  22:39 Найти цитируемый пост)
Доброго времени суток.Задача такая, многопоточная закачка файлов из интернета (один пото - один файл). Так вот собственно интересует как можно проверить максимальное кол-во потоков (соединений), которое можно установить не в ущерб производительности?



Понятие "ущерб производительности" весьма размыто. 

Максимально допустимое число открытых соединений зависит от настроек ОС.

Было время, писал я всякие парсеры на Java.  Обычно делал 300-600 потоков в зависимости от характеристик сервера. 

п.с. если выкачиваете текст, имейте ввиду, что stringBuilder рулит smile ( избегайте использование "+" в потоках при получении текстовых данных с сокета )

Автор: CSharpProgrammer 21.6.2012, 01:45
Vasay, 
Цитата(Vasay @  21.6.2012,  01:32 Найти цитируемый пост)
Понятие "ущерб производительности" весьма размыто. 


Спасибо. Под понятием "ущерб производительности" я имел ввиду тот придел до которго увеличение потоков будет приводить к увеличению скорости работы парсера. Т.е. как я понял все упирается в настройки ОС и ширину канала?


Автор: Vasay 21.6.2012, 01:48
Цитата(CSharpProgrammer @  21.6.2012,  01:45 Найти цитируемый пост)
 Т.е. как я понял все упирается в настройки ОС и ширину канала?


И в то, что Вы делаете внутри потока. Я не просто так написал про "+" и stringBuilder  smile 

Автор: CSharpProgrammer 21.6.2012, 01:55
Цитата(Vasay @  21.6.2012,  01:48 Найти цитируемый пост)
И в то, что Вы делаете внутри потока.


Теперь все ясно. Спасибо за помощь!

П.С. А пример парсера случайно не сохранился?  smile 

Автор: Vasay 21.6.2012, 02:15
Цитата(CSharpProgrammer @  21.6.2012,  01:55 Найти цитируемый пост)
П.С. А пример парсера случайно не сохранился? 


Выложить исходники я не могу, но готов ответить на конкретные вопросы. 

Автор: CSharpProgrammer 21.6.2012, 02:39
Цитата(Vasay @  21.6.2012,  02:15 Найти цитируемый пост)
готов ответить на конкретные вопросы. 


Основной вопрос это как организована работа потоков в таком приложении (т.е. как правильно организовать). К примеру на входе 100К ссылок. В данный момент у меня реализована следующая архитектура

Код

public class DownloadThreadPoolExecutor extends ThreadPoolExecutor {

    ...

    public DownloadThreadPoolExecutor(int poolSize) {
        super(poolSize, poolSize, 9223372036854775807L, TimeUnit.SECONDS, new LinkedBlockingDeque());
        this.poolSize = poolSize;
    }

    public void start() {
        for (int i = 0; i < this.poolSize; i++) {
            submit(new DownloadThread(Producer.getInstance()));
        }
    }

    ...
}


И каждый поток берет у Producer свою порцию данных.

Так правильно? И какие варианты еще есть?

Автор: Vasay 21.6.2012, 03:26
Цитата(CSharpProgrammer @  21.6.2012,  02:39 Найти цитируемый пост)
Так правильно? И какие варианты еще есть?



Когда я начинал писать парсерный движок, ThreadPoolExecutor вроде еще не было (или я просто о нем знал на тот момент smile ). 

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

Потоки за новыми данными обращались к synchronized методу. 

Сохранение данных шло разными путями, в зависимости от того, чего хотел добиться.  В самом нагруженном случае, каждый поток обрабатывал данные,  и результат обработки сохранялся (дописывал) в файл через synchronized метод использовавший единый для всех потоков BufferedWriter. Формат файла был предназначен для быстрой загрузки в базу с помощью LOAD DATA INFILE - это был самый быстрый способ загрузить данные в MySQL с построением индексов (нужен был быстрый поиск по текстовым полям в таблицах со 100мл записей).

Не уверен что это оптимальный вариант (тем более на сегодняшний день) Но это работало и работало быстро. 100 мегабитный канал сервера забивал. 


Автор: CSharpProgrammer 21.6.2012, 13:00
Vasay, 

Спасибо за развернутый ответ. Тему можно закрывать.

Автор: Flashed 27.6.2012, 15:21
Вообще, чтобы не завалить ОС,нужно использовать пул потоков. Сегодня защитил диплом на эту тему!!! 
Вот отличная статья: http://www.ibm.com/developerworks/ru/library/j-jtp0730/

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)