4

我正在尝试使用 selenium webdriver 作为查询/浏览器来设置生产者/消费者。

运行以下代码时,并非所有查询都实际输入,即使输出显示它们是。一些查询也要么加倍(即“Fish”变为“FisFishh”)。

应用程序

public class App {

    public static void main(String[] args) {

        DriverHashMap.init();

        Executor exec = new Executor();

        // Add queries to list
        Query query = new Query(exec);
        query.addQuery("Cats");
        query.addQuery("Dogs");
        query.addQuery("Fish");
        // query.addQuery("Bats");
        // query.addQuery("Rats");
        // query.addQuery("Geese");

        ExecutorService threadPool = Executors.newFixedThreadPool(4);

        // Submit queries to pool
        Future queryStatus = threadPool.submit(query);

        // Start browsers
        threadPool.execute(new Browser("1", exec));
        threadPool.execute(new Browser("2", exec));

        // this will wait for the producer to finish its execution.
        try {
            queryStatus.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        // Wait for pool to finish
        threadPool.shutdown();

    }
}

浏览器

public class Browser implements Runnable {
    private String name;
    private Executor exec;

    private static WebDriver driver;
    private static String baseURL = "http://www.google.com";
    private static String query;

    public Browser(String name, Executor exec) {

        synchronized (this) {
            this.name = name;
            this.exec = exec;

            System.out.println("\tStart Browser-" + this.name);
            driver = new FirefoxDriver();
            // Wait up to 30 seconds for a response
            driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

            DriverHashMap.addDriver(name, driver);
            System.out.println("\tAdded Browser-" + name + " to hashmap");
        }

    }

    private void enterQuery() {

        synchronized (this) {
            // Get driver for this browser
            driver = DriverHashMap.getDriver(this.name);
            System.out.println("Browser " + this.name
                    + " entering query from executor: " + query);

            // Search field qbqfq
            driver.findElement(By.id("gbqfq")).clear();

            // Enter query
            driver.findElement(By.id("gbqfq")).sendKeys(query);

            // Click search button
            driver.findElement(By.id("gbqfb")).click();
        }

    }

    public void run() {
        try {

            synchronized (this) {
                // Receive first query
                driver = DriverHashMap.getDriver(this.name);
                query = exec.get();
                System.out.println("Browser " + this.name
                        + "\n\rReceived first query from executor: " + query);
            }

            do {

                synchronized (this) {
                    // Process query
                    driver = DriverHashMap.getDriver(this.name);
                    driver.get(baseURL);
                    enterQuery();
                }

                synchronized (this) {
                    // Receive next query
                    query = exec.get();
                    driver = DriverHashMap.getDriver(this.name);
                    System.out.println("Browser " + this.name
                            + "\n\rReceived new query from executor: " + query);
                }

            } while (query != null);

            // Close this browser
            synchronized (this) {
                driver = DriverHashMap.getDriver(this.name);
                System.out.println("Browser " + this.name
                        + " finished its job; terminating.");

                driver.close();
            }

        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

}

询问

public class Query implements Runnable {
    private Executor exec;
    private List<String> queries = new ArrayList<String>();

    public Query(Executor exec) {
        this.exec = exec;
    }

    public void addQuery( String query ) {
        System.out.println("Adding " + query + " to queries");
        queries.add( query );
    }

    public void run() {

        Iterator it = queries.iterator();
        String currQuery = new String();

        try {
            while( it.hasNext()) {
                currQuery = (String)it.next();
                System.out.println("Adding " + currQuery + " to Executor");
                exec.put(currQuery);
            }

            this.exec.continueProducing = Boolean.FALSE;
            System.out.println("Query has finished its job; terminating.");
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

    }
}

执行者

public class Executor {
    public ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(
            100);
    public Boolean continueProducing = Boolean.TRUE;

    public void put(String query) throws InterruptedException {
        this.queue.put(query);
    }

    public String get() throws InterruptedException {
        return this.queue.poll(1, TimeUnit.SECONDS);
    }
}
4

1 回答 1

3

Webdriver 本身不是线程安全的。尝试将其包装成ThreadLocal

在类似的情况下,这对我有很大帮助。

于 2013-04-30T05:54:45.710 回答