我在一个实现Callable的类中有这个:
public class MasterCrawler implements Callable {
public Object call() throws SQLException {
resumeCrawling();
return true;
}
//more code with methods that throws an SQLException
}
在执行此Callable的其他类中,如下所示:
MasterCrawler crawler = new MasterCrawler();
try{
executorService.submit(crawler); //crawler is the class that implements Callable
}(catch SQLException){
//do something here
}
但我得到一个错误和IDE的消息,SQLException永远不会抛出。这是因为我在ExecutorService中执行?
UPDATE :因此提交不会抛出SQLException。我如何执行Callable(作为线程运行)并捕获异常?
解决:
public class MasterCrawler implements Callable {
@Override
public Object call() throws Exception {
try {
resumeCrawling();
return true;
} catch (SQLException sqle) {
return sqle;
}
}
}
Future resC = es.submit(masterCrawler);
if (resC.get(5, TimeUnit.SECONDS) instanceof SQLException) {
//do something here
}
答案 0 :(得分:2)
当您致电submit
时,您正在传递一个对象。你没有打电话给call()
。
修改强>
Submit
返回Future f。当您调用f.get()
时,如果在执行callable期间遇到问题,该方法可以抛出ExecutionException。如果是这样,它将包含call()
抛出的异常。
通过将您的Callable提交给执行程序,您实际上是要求它执行它(异步)。无需采取进一步行动。只需找回未来并等待。
关于解决方案
虽然您的解决方案可行,但这不是很干净的代码,因为您正在劫持Call的返回值。尝试这样的事情:
public class MasterCrawler implements Callable<Void> {
@Override
public Void call() throws SQLException {
resumeCrawling();
return null;
}
public void resumeCrawling() throws SQLException {
// ... if there is a problem
throw new SQLException();
}
}
public void doIt() {
ExecutorService es = Executors.newCachedThreadPool();
Future<Void> resC = es.submit(new MasterCrawler());
try {
resC.get(5, TimeUnit.SECONDS);
// Success
} catch ( ExecutionException ex ) {
SQLException se = (SQLException) ex.getCause();
// Do something with the exception
} catch ( TimeoutException ex ) {
// Execution timed-out
} catch ( InterruptedException ex ) {
// Execution was interrupted
}
}
答案 1 :(得分:1)
submit方法不会抛出SQLException。
答案 2 :(得分:0)
这是因为SQLException永远不会被爬虫抛出。
尝试使用finally
代替catch
,看看您是否会遇到问题或是否有效。
答案 3 :(得分:0)
您使用的是什么IDE?当我尝试你的代码时,Eclipse抱怨“未处理的异常类型异常”。这是有道理的,因为Callable
接口定义了call()
方法以抛出Exception
。仅仅因为您的实现类声明了一个更受限制的异常类型,调用程序就不能指望它。它希望你能捕获异常。