我在一个实现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永远不会抛出。这是因为我在执行器服务中执行?
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
}
当您调用submit
时,您正在传递一个对象。您不是在呼叫call()
。
编辑
Submit
返回Future f。当您调用f.get()
时,如果在执行可调用的过程中遇到问题,该方法可以抛出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
}
}
这是因为爬网程序永远不会抛出SQLException。
试着使用finally
而不是catch
,看看你是否会遇到问题或它是否有效。
您使用的是什么IDE?当我尝试您的代码时,Eclipse会抱怨"未处理的异常类型exception"。这是有意义的,因为Callable
接口定义了抛出Exception
的call()
方法。仅仅因为实现类声明了一个更受限制的异常类型,调用程序就不能指望它。它希望您捕获Exception。