思路:频繁开关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实现
版权声明:本文为hqq2023623原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。