【问题标题】:Runnable inside for-loop可在 for 循环内运行
【发布时间】:2019-03-20 20:06:02
【问题描述】:

我想在线程中的 for 循环内运行代码,因为它几乎会执行相同的操作,但针对不同的页面(使用 selenium webdriver)。我的问题是,我的计数器变量不能增加,因为它必须是最终的......

这是我的测试代码,但变量“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();
        }

谁能帮我在我的 chromedriver 的每个选项卡中并行执行相同的操作?

【问题讨论】:

  • 您可以将计数器包装到一个数组中以使其保持可变,但使用AtomicInt 会更简单。但。 WebDriver 是有状态的,不是为多线程使用而设计的。每个线程实例化 WebDriver(从而启动浏览器实例)会更安全。
  • 只是想知道:您没有在这里接受答案的具体原因是什么?

标签: java selenium for-loop web-scraping selenium-chromedriver


【解决方案1】:

我认为你走错了兔子洞。看看你的代码:

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

您希望 webDriver 切换到另一个窗口。然后在该选项卡上做一些事情。但是如果第一行和第二行之间有线程的上下文切换呢?!

如:

  • 线程A:webDriver.switchTo()
  • 线程B:webDriver.switchTo()
  • 线程 A:打印页面标题

显然这会导致竞争条件!当然,您可以添加某种锁定/同步,以便线程始终切换到 a 选项卡并完成其工作,同时另一个线程无法更新 webDriver 对象。但这基本上会序列化您的测试。

长话短说:webDriver 对象具有 internal 状态。您的方法完全忽略了这一事实,因此无法预测您的代码究竟会做什么。

一个简单的解决方法是为每个线程实例化一个 WebDriver 实例,如 cmets 中所建议的那样。除此之外,有关如何以与 selenium “思考”并行测试的方式相匹配的方式以不同方式执行此操作的想法,请参阅 here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多