Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> spring bean многопоточное использование 
:(
    Опции темы
Samotnik
Дата 10.1.2012, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



Привет.
Ситуация такая: Есть спринг бин ProxyKeeper, содержит в себе два поля: IP, port. Этот бин используется для реализации прокси сервера, а точнее, он в себе содержит адреса нескольких прокси серверов(в данном случае пять), которые должны последовательно меняться, если один перестает работать.
Код

<bean id="proxyKeeper" class="com.my.project.core.ProxyKeeper">
     <property name="proxyList">
         <list>
             <bean class="com.my.project.core.ProxySocket">
                 <constructor-arg index="0">
                     <value>0.0.0.0</value>
                 </constructor-arg>
                    <constructor-arg index="1">
                        <value>8080</value>
                    </constructor-arg>
             </bean>
             <bean class="com.my.project.core.ProxySocket">
                 <constructor-arg index="0">
                     <value>1.1.1.1</value>
                 </constructor-arg>
                    <constructor-arg index="1">
                        <value>80</value>
                    </constructor-arg>
             </bean>
             <bean class="com.my.project.core.ProxySocket">
                 <constructor-arg index="0">
                     <value>2.2.2.2</value>
                 </constructor-arg>
                    <constructor-arg index="1">
                        <value>6515</value>
                    </constructor-arg>
             </bean>
             <bean class="com.my.project.core.ProxySocket">
                 <constructor-arg index="0">
                     <value>3.3.3.3</value>
                 </constructor-arg>
                    <constructor-arg index="1">
                        <value>80</value>
                    </constructor-arg>
             </bean>
             <bean class="com.my.project.core.ProxySocket">
                 <constructor-arg index="0">
                     <value>4.4.4.4</value>
                 </constructor-arg>
                    <constructor-arg index="1">
                        <value>3128</value>
                    </constructor-arg>
             </bean>
         </list>
     </property>
     <property name="activeProxy" value="0" />
    </bean>

Логика  метода, который это все обрабатывает обсолютно не сложная. С помощью библиотеки htmlcleaner загружается URL, и достается все html содержимое.:
Код

    public Element loadUrl(String url) {
        Element result = null;
        boolean isNeedTryNextIP = true;
        int activeProxy = proxyKeeper.getActiveProxy();
        List<ProxySocket> proxyList = proxyKeeper.getProxyList();
        String ip = "";
        int port = 0;
        while (isNeedTryNextIP) {
            isNeedTryNextIP = false;
            try {
                URL urlObject = new URL(url);
                URLConnection urlConnection = null;
                if (proxyList != null && !proxyList.isEmpty()) {
                    ip = proxyList.get(activeProxy).getIp();
                    //move it to proxy keeper
                    port = Integer.valueOf(proxyList.get(activeProxy).getPort());
                    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ip, port));
                    logger.info("Proxy is set.");
                    urlConnection = urlObject.openConnection(proxy);
                } else {
                    logger.info("There are no one proxy address!");
                    urlConnection = urlObject.openConnection();
                }
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                Document doc = db.parse(urlConnection.getInputStream());
                Element root = doc.getDocumentElement();
                result = root;
            } catch (ParserConfigurationException e) {
                logger.debug("Can not configure the parser. {}", e.getMessage());
            } catch (SAXException e) {
                logger.debug("Can not parse the page. {}", e.getMessage());
            } catch (IOException e) {
                logger.info("IP: {} and port: {} are not valid, use next.", ip, port);
                logger.info(e.getMessage());
                ++activeProxy;
                if (activeProxy >= proxyList.size()) {
                    logger.info("Warning! There are no more valid IP addresses! Check them again");
                    activeProxy = 0;
                }
                proxyKeeper.setActiveProxy(activeProxy);
                isNeedTryNextIP = true;
            }
        }
        return result;
    }

Вопрос вот в чем, этот метод могут использовать одновременно от одного до пятнадцати других методов, как одновременно, так и нет. Вопрос: будет ли этот метод корректно отрабатывать каждый раз? Особенно интересует переменная activeProxy, будет ли она меняться всегда, как этого требует алгоритм, или для каждого метода вызывающего этот метод, она будет своя?

Это сообщение отредактировал(а) Samotnik - 10.1.2012, 14:12
PM MAIL   Вверх
Stolzen
Дата 10.1.2012, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1041
Регистрация: 17.10.2005

Репутация: 3
Всего: 48



Цитата(Samotnik @  10.1.2012,  15:11 Найти цитируемый пост)
Вопрос: будет ли этот метод корректно отрабатывать каждый раз? Особенно интересует переменная activeProxy, будет ли она меняться всегда, как этого требует алгоритм, или для каждого метода вызывающего этот метод, она будет своя?

Будет ли она меняться зависит от proxyKeeper, в этом ведь методе она после присвоения больше не изменяется. Попробуйте ее выставить в final. 
Что имеется ввиду под "она будет своя"? Для каждого вызова в стеке будет своя переменная, доступ к которой будет возможен только из этого метода - поэтому одновременное использование переменной из разных потоков невозможно в принципе.


--------------------
datatalks.ru - анализ данных, статистика, машинное обучение
PM MAIL WWW   Вверх
MisterCleric
Дата 10.1.2012, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1043
Регистрация: 16.2.2006
Где: Харьков, Украина

Репутация: 33
Всего: 38



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

 proxyKeeper.setActiveProxy(activeProxy);

Надо в ProxyKeeper использовать ReadWriteLock на проперти activeProxy
Код

 private final ReadWriteLock rwl = new ReentrantReadWriteLock();
 private final Lock r = rwl.readLock();
 private final Lock w = rwl.writeLock();

public int getActiveProxy() {
        r.lock();
         try {
        ....
       }
        finally { 
          r.unlock(); 
        }
}
...
public void setActiveProxy(int activeProxy) {
          w.lock();
          try { 
            .... 
            }
          finally { 
            w.unlock();
          }
}



Это сообщение отредактировал(а) MisterCleric - 10.1.2012, 15:12


--------------------
ПРИШЕЛ, УВИДЕЛ - ПЕРЕПИСАЛ...
PM MAIL ICQ   Вверх
Samotnik
Дата 10.1.2012, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 5
Всего: 191



StolzenMisterCleric,  почему переменные final ? Мне как раз-таки наоборот нужно изменять их значения.
Т.е.: метод берет первые ip, port. пытается отработать, не получается, выскакивает IOException, в catch я я беру следующую пару ip, port. И так должно быть до бесконечности по кругу. 
Меня интересует, если метод установил, что активный порперти, например третий, будет ли другой метод, который тоже паралельно работает с этим же методом, поринформирован, что нужно использовать третью пару?
PM MAIL   Вверх
Stolzen
Дата 10.1.2012, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1041
Регистрация: 17.10.2005

Репутация: 3
Всего: 48



Цитата(Samotnik @  10.1.2012,  16:47 Найти цитируемый пост)
Stolzen, MisterCleric,  почему переменные final ? Мне как раз-таки наоборот нужно изменять их значения

Если нужно менять значения, то это уже означает, что потенциально код потоконебезопастный. 

Цитата(Samotnik @  10.1.2012,  16:47 Найти цитируемый пост)
Т.е.: метод берет первые ip, port. пытается отработать, не получается, выскакивает IOException, в catch я я беру следующую пару ip, port. И так должно быть до бесконечности по кругу. 

Тогда сделайте 
Код

int activeProxy = proxyKeeper.getActiveProxy();

В цикле, после while

Добавлено через 6 минут и 57 секунд
А вообще архитектурно следовало бы использовать другой подход. Можно выделить класс, который будет знать, какой прокси сейчас активен, и в loadUrl использовать его - сейчас loadUrl делает слишком много действий. 


--------------------
datatalks.ru - анализ данных, статистика, машинное обучение
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0722 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.