Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程/并发运行selenium Windows_Java_Multithreading_Selenium - Fatal编程技术网

Java 多线程/并发运行selenium Windows

Java 多线程/并发运行selenium Windows,java,multithreading,selenium,Java,Multithreading,Selenium,我目前正在进行一个项目,使用selenium和phantomJS 我写的项目运行良好,但问题是它非常慢,所以我想我可能会在其中引入多线程 我知道selenium不是多线程安全的,每个线程都应该有自己的webdriver(为了清楚起见) 重点是: 我有一个包含url中使用的对象的数组(只是其中的一部分) 目前,我正在为对象运行for循环,并将驱动程序导航到给定的xpath,获取数据并初始化对象。为了更快,我想创建4个线程,每个线程应该: 初始化新的web驱动程序 从列表中获取尚未使用的项 在此对象

我目前正在进行一个项目,使用selenium和
phantomJS

我写的项目运行良好,但问题是它非常慢,所以我想我可能会在其中引入多线程

我知道selenium不是多线程安全的,每个线程都应该有自己的webdriver(为了清楚起见)

重点是:

我有一个包含url中使用的对象的数组(只是其中的一部分) 目前,我正在为对象运行for循环,并将驱动程序导航到给定的xpath,获取数据并初始化对象。为了更快,我想创建4个线程,每个线程应该:

  • 初始化新的web驱动程序

  • 从列表中获取尚未使用的项

  • 在此对象上调用不同的函数

  • 我不确定我应该如何开始创建多个驱动程序并将其全部放在一起。我该如何创建负责工作的线程?我已经读过关于runoverride函数的内容,这里应该有线程应该做的工作,但是它应该如何知道列表中要使用的下一个元素呢

    到目前为止,我有以下几点:

    public static class MyThread implements Runnable {
            private Objectx object
            private WebDriver driver;
            public MyThread(Objectx object){
                this.object = object;
            }
            @Override
            public void run() {
                driver = driverSettings(driver);
                driver.navigate().to("website" + object.getNumber + ".html");
                function1(object);
                function2(object);
             }
        }
    
    在主要方法中:

            ExecutorService executor = Executors.newFixedThreadPool(4);
    
    现在我有了对象列表

        private static List<Objectx> listOfObjects = new ArrayList<Objectx>();
    

    或者如何添加所有对象以创建可运行列表?

    以下是基本步骤

    1) 创建一个线程池。线程的数量不取决于要处理的对象的大小。例如,您可以创建一个包含4个线程的池来处理250个对象

    2) 创建线程时,将对象列表传递给其构造函数

    3) 每个线程从列表中获取下一个对象并将其从列表中删除。您可以使用队列而不是列表

    4) 重要提示:应该同步对列表(队列)的访问,以便一次只有一个线程可以修改它。最简单的方法之一是使用ConcurrentLinkedQueue

    5) run()中的每个线程从列表(从队列)中检索下一个任务,处理它,检索下一个任务。如果没有其他任务,线程将退出其run()方法

    更新1:(问题更新后)

    “MyThread”这个名称是误导性的,因为它不是一个线程。我建议你根据它的功能来命名它,比如“WebSiteParser”。但对于功能结果来说,这并不重要:)

    创建runnable实例时,应将其提交给执行器。它将根据池中的线程数执行它们

    更新2:


    关于Web驱动程序的重用:如果您使用ExecutorService,那么我建议您提前创建Web驱动程序,将它们放入堆栈或队列中。当一个线程开始它的任务时,它应该从这个堆栈或队列中获取一个Web驱动程序。当它完成任务时,应该将其Web驱动程序放回堆栈或队列。再次确保对该堆栈或队列的访问是线程安全的。

    解释您希望使用两个线程更快的部分,以及为什么您认为它会更快。@mentalurg,它会更快,因为我可以同时打开多个浏览器窗口并使用它们。因此每个线程都有自己的任务。那到底是什么问题?是的。问题是我应该使用什么以及如何准确地使用它。如何创建给定数量的线程并在给定的对象列表上执行它们。我设法让它在线程上运行(如果我有fx4个对象,它会创建4个线程,但问题是如果我有250个对象),你是否试图以并行模式运行测试脚本以节省时间?我已经编辑了这个问题,你介意看一看吗?太棒了!我设法做到了。但我还有一个问题。每当我调用run命令时,我都会创建新的驱动程序。是否可以列出这些线程,并且每个线程都应该获得“免费”驱动程序?或者每个根目录在一生中保留相同的驱动程序?
    For (Objectx object : listOfObjects){
            Runnabble object.getNumber() = new MyThread(object).start()
    }