简单的Selenium访问控制线程池

来源:互联网 发布:linux 开机自启动脚本 编辑:程序博客网 时间:2024/06/06 00:54

思路:频繁开关phantomJS进程比较耗费资源,所以需要维护一个线程池控制访问以减少内存消耗


1. 自定义操作CustomAction接口

public interface CustomAction {    String action(WebDriver webDriver);}

2. WebDriverPool池

public class WebDriverPool {    // 线程池大小    private static final int MAX_COUNT = 15;    // 线程数量控制    private Semaphore semaphore = new Semaphore(MAX_COUNT);    // webDriver池    private WebDriver[] webDrivers = new WebDriver[MAX_COUNT];    private boolean[] driverFlag = new boolean[MAX_COUNT];    private Lock lockDrivers = new ReentrantLock();    //phantomjs路径    private final String JS_BIN = "f:/phantomjs";    public WebDriverPool() {        System.setProperty("phantomjs.binary.path", JS_BIN);        for (int i = 0; i < MAX_COUNT; i++) {            driverFlag[i] = true;        }        // 关闭所有打开的浏览器        Runtime.getRuntime().addShutdownHook(new Thread(() -> {            for (WebDriver webDriver : webDrivers) {                if (webDriver != null) {                    webDriver.quit();                }            }        }));    }    /**     * 生成一个新的PhantomJSDriver     */    private WebDriver defaultDriver() {        DesiredCapabilities cap = DesiredCapabilities.phantomjs();        // 优化命令行参数        List<String> cmdList = new ArrayList<>();        // 禁用图片        cmdList.add("--load-images=false");        // 本地缓存        cmdList.add("--disk-cache=true");        cap.setCapability("phantomjs.cli.args", cmdList);        return new PhantomJSDriver(cap);    }    /**     * 获取当前空闲的driver的下标     *     * @return 当前空闲的driver的下标     */    private int freeDriverIndex() {        int ret = -1;        try {            lockDrivers.lock();            for (int i = 0; i < driverFlag.length; i++) {                if (driverFlag[i]) {                    driverFlag[i] = false;                    ret = i;                    break;                }            }            if (ret != -1) {                if (webDrivers[ret] == null) {                    webDrivers[ret] = defaultDriver();                }            }        } finally {            lockDrivers.unlock();        }        return ret;    }    /**     * 获取执行js之后的页面html     */    public String customJs(CustomAction action) {        String html = "";        try {            semaphore.acquire();            int index = freeDriverIndex();            //调用自定义的操作            html = action.action(webDrivers[index]);            driverFlag[index] = true;        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            semaphore.release();        }        return html;    }}

缺点:

1.不能在运行时自由伸缩线程池中的资源,也就是不能在闲时销毁池中的资源减少内存消耗 ,运行时不能很好地伸缩

2.每个PhantomJS进程只运行了一个窗口,比较浪费,可以通过PhantomJSDriverService结合RemoteWebDriver的方式支持更高的并发

3.考虑使用apache commons pool2实现



0 0
原创粉丝点击