Runnable внутри для цикла - PullRequest
       14

Runnable внутри для цикла

0 голосов
/ 20 марта 2019

Я хочу запустить код внутри цикла for в потоке, потому что он почти будет делать то же самое, но для разных страниц (с селеновым веб-драйвером).Моя проблема в том, что моя переменная-счетчик не может увеличиваться, потому что она должна быть конечной ...

Это мой тестовый код, но переменная "tabCount" всегда остается со счетом i.

// scrape over all tabs and get data in threads
        for (int i = 0; i < tabs.size(); i++) {
            final int tabCount = i;

            Runnable r = () -> {
                webDriver.switchTo().window(tabs.get(tabCount));
                System.out.println(webDriver.getTitle());
            };

            threadPool.execute(r);
        }

        threadPool.shutdown();
        try {
            threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

Может ли кто-нибудь помочь мне выполнить одну и ту же операцию параллельно на каждой вкладке моего хроматографа?

1 Ответ

3 голосов
/ 20 марта 2019

Я думаю, что вы спускаетесь не в ту кроличью нору. Посмотрите на ваш код:

webDriver.switchTo().window(tabs.get(tabCount));
System.out.println(webDriver.getTitle());

Вы хотите, чтобы webDriver переключился на другое окно. А затем сделайте что-нибудь на этой вкладке. Но что, если между первой и второй строкой есть контекстный переключатель потоков ?!

Как в:

  • нить A: делает webDriver.switchTo()
  • резьба B: делает webDriver.switchTo()
  • Тема A: печатает заголовок страницы

Очевидно, это приведет к условиям гонки! Конечно, вы можете добавить своего рода блокировку / синхронизацию, чтобы поток всегда переключался на вкладку и выполнял свою работу, при этом другой поток не мог обновлять объект webDriver за это время. Но это в основном сериализует ваше тестирование.

Короче говоря: объект webDriver имеет внутреннее состояние. Ваш подход полностью игнорирует этот факт, поэтому невозможно предсказать, что именно будет делать ваш код.

Простым решением будет создание одного экземпляра WebDriver на поток, как предлагается в комментариях. Кроме того, для идеи, как сделать это по-другому, в соответствии с тем, как селен «думает» о параллельных тестах, см. здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...