Java HtmlUnit WebClient重置线程中断状态
我有一堆解析器类,它们是PriseParser类的子类,并实现了PriseParser.getPrices调用的getAllPrices方法,该方法还做了一些与本文无关的事情,以便从各种网站获取一些数据。以下是此类实施的示例:Java HtmlUnit WebClient重置线程中断状态,java,multithreading,interrupt,htmlunit,executorservice,Java,Multithreading,Interrupt,Htmlunit,Executorservice,我有一堆解析器类,它们是PriseParser类的子类,并实现了PriseParser.getPrices调用的getAllPrices方法,该方法还做了一些与本文无关的事情,以便从各种网站获取一些数据。以下是此类实施的示例: @Override public List<Price> getAllPrices() throws ParserException, InterruptedException { LogFactory.getFactory().se
@Override
public List<Price> getAllPrices() throws ParserException,
InterruptedException {
LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog");
java.util.logging.Logger.getLogger("com.gargoylesoftware.htmlunit")
.setLevel(Level.OFF);
java.util.logging.Logger.getLogger("org.apache.commons.httpclient")
.setLevel(Level.OFF);
List<Price> prices = new ArrayList<price>();
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
HtmlPage page;
try {
page = webClient.getPage(URL);
if(Thread.currentThread().isInterrupted()){
System.out.println("INTERRUPTED BEFORE CLOSE");
}
//my parsing code here that fills prices list. Includes calls to webClient.waitForBackgroundJavaScript in some places
webClient.closeAllWindows();
if(Thread.currentThread().isInterrupted()){
System.out.println("INTERRUPTED AFTER CLOSE");
}
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
throw new ParserException(e);
}
return prices;
}
这些解析器与ExecutorService并行运行:
public List<Price> getPrices(List<PriceParser> priceParsers) throws InterruptedException {
ExecutorService executorService = Executors
.newFixedThreadPool(PriceParsers.size());
Set<Callable<List<Price>>> callables = new HashSet<Callable<List<Price>>>();
List<Price> allPrices = new ArrayList<Price>();
for (PriceParser PriceParser : PriceParsers) {
callables.add(new Callable<List<Price>>() {
public List<Price> call() throws Exception {
List<Price> prices = new ArrayList<Price>();
prices = PriceParser.getPrices();
return prices;
}
});
}
List<Future<List<Price>>> futures;
try {
futures = executorService.invokeAll(callables);
for (Future<List<Price>> future : futures) {
allPrices.addAll(future.get());
}
} catch (InterruptedException e) {
throw e;
} catch (ExecutionException e) {
logger.error("MULTI-THREADING EXECUTION ERROR ", e);
throw new RuntimeException("MULTI-THREADING EXECUTION ERROR ", e);
} finally {
executorService.shutdownNow();
}
return allPrices;
}
在第一个方法中添加了两个ifThread.currentThread.isInterrupted{}段代码,以检查我观察到的以下问题:当executor服务中断时,gui应用程序会在按下取消按钮时终止线程,我在代码中插入的第一个中断检查成功地打印了“关闭前中断”
但是,第二个检查不会打印任何内容。因此,似乎我对webClient的调用中有一个是waitForBackgroundJavaScript方法调用,最后的webClient.closeAllWindows调用清除了线程中断状态。有人能解释为什么会发生这种情况吗?问题似乎在于我的解析代码对webClient.waitForBackgroundJavaScript的调用。在内部,这可以延伸到HtmlUnit的JavaScriptJobManagerImpl方法的waitForJobs方法。此方法包含以下代码段,基本上包含所有InterruptedException,因此任何调用方都能够识别在该调用期间是否发生了中断:
try {
synchronized (this) {
wait(end - now);
}
// maybe a change triggers the wakup; we have to recalculate the
// wait time
now = System.currentTimeMillis();
}
catch (final InterruptedException e) {
LOG.error("InterruptedException while in waitForJobs", e);
}
它应该让异常被抛出,而不是捕获和记录