![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Temdegon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.10.2008 Где: Minsk Репутация: 7 Всего: 9 |
Кое-как написал код для поиска рабочих proxy-серверов из списка в файле.
Но программа работает очень медленно из-за того, что для проверки серверов используется только один поток. Помогите пожалуйста переделать этот код так, что бы серверы проверялись в несколько потоков параллельно. Нужно как-то сделать, что бы вместо вызова метода checkProxy создавался и стартовался новый поток, который бы делал то же самое, что и этот метод. Потом нужно как-то контролировать, сколько потоков уже работает, что бы не создать их слишком много. Есть еще одна вещь, которую я просто взял из FAQ (спасибо Platon). При работе с HttpClient, в трех местах задается таймаут. Но за что конкретно отвечает каждый из них мне непонятно. Обьясните плиз. И в каком случае мы получим IOException в методе checkProxy? А еще хотелось бы услышать любые замечания по этому коду. По улучшению производительности, по оформлению и т.д.
|
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Создаешь ThreadPoolExecutor и запускаешь его. Затем читаешь список прокси и для каждого прокси сервера создаешь новый таск (какой нибудь Callable<ProxyCheckResult>). Все Future<ProxyCheckResult> складываешь в лист. После того как засабмитил все прокси, идешь по списку и получаешь результат выполнения для каждого Future<ProxyCheckResult> и выводишь его куда требуется. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| AntonSaburov |
|
|||
![]() Штурман ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 5658 Регистрация: 2.7.2002 Где: Санкт-Петербург Репутация: 51 Всего: 118 |
Вообщем-то совсем не проблема выделить нужный метод в отдельный класс, который либо наследуется от Thread, либо реализцет интерфейс Runnable. Тогда им можно управлять, смотреть его состояние и прочая - см. Thread
По поводу ограничения - можно использовать Semaphore - описание есть в API Doc. Ну или тут приличное описание - http://java.sun.com/developer/technicalArt...SE/concurrency/ |
|||
|
||||
| Temdegon |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.10.2008 Где: Minsk Репутация: 7 Всего: 9 |
Что-то я не совсем понял с этими ThreadPoolExecutor, Callable и Future. Самих адресов, которые мне нужно проверить может быть очень много - тысячи, а может и десятки тысяч, т.к. прога сама будет их собирать по инету. Но одновременно должно выполняться некое фиксированное число потоков, которое можно было бы выставлять, в зависимости от пропускной способности канала - я думаю, штук 20-50. Не совсем врубился, какое из чисел, передаваемых в конструктор ThreadPoolExecutor за это отвечает. Еще меня смущает тот факт, что будет создаваться и висеть в памяти очень много обьектов Callable и Future. Не будет ли это поводом для OutOfMemory?
В главном классе код запуска выглядит примерно так:
А сам Callable вот так:
Result
new ThreadPoolExecutor(10, 100, 10000, TimeUnit.SECONDS, queue); - что здесь означают параметры? из документации я ничего толком не понял. Как узнать, что все потоки завершились? Как правильно завершить Executor? |
||||||
|
|||||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
ThreadPoolExecutor-у надо задать максимальное количество потоков которые будут проверять прокси. Самому создавать Future не надо, их создаст и вернет тебе ThreadPoolExecutor когда ты засабмитишь ему Callable. У Future есть два метода чтобы получить результат: один ждет бесконечно, второй определённое время.
Как-то так это должно выглядеть.
(конечно это просто пример, а не то как должен выглядеть реальный код) -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| Temdegon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.10.2008 Где: Minsk Репутация: 7 Всего: 9 |
Спасибо LSD, буду разбираться. А за что отвечает первое число в конструкторе?
Я так понимаю, сюда
зайдет только после того, как потоки отработают? |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Умолчальное количество потоков. После создания в пуле будет именно такое количество потоков. Параметр имеет значение для пулов которые могут быть нагружены работой частично. В этой задаче этот параметр не важен.
Нет. Сюда он зайдет после того как засабмитит все таски. Future.get() блокируемый метод, он ждет пока не будет готов результат. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| Temdegon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 429 Регистрация: 11.10.2008 Где: Minsk Репутация: 7 Всего: 9 |
Еще раз спасибо. Основные моменты вроди бы прояснились, и я думаю, что все получится
|
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Небольшое уточнение: При вызове конструктора, эти потоки не создаются. Они создаются в первые n-вызовов методов, предназначенных для постановки заданий. Чтобы потоки ко времени постановки заданий уже были бы созданы, нужно явно вызвать ThreadPoolExecutor#setCorePoolSize(int corePoolSize); |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Тогда уж лучше prestartAllCoreThreads() или prestartCoreThread() если нужно стартовать один поток. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |