1

我在一个实现 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 中执行?

更新:所以提交不会引发 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
}
4

4 回答 4

2

当您调用 时submit,您正在传递一个对象。你没有打电话call()

编辑

Submit返回一个未来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

    } 

}
于 2011-05-27T02:05:33.193 回答
1

提交方法不会抛出 SQLException。

于 2011-05-27T02:04:39.517 回答
0

这是因为爬虫永远不会抛出 SQLException。

尝试使用finally代替,catch看看您是否会遇到问题或它是否有效。

于 2011-05-27T02:05:01.773 回答
0

你用的是什么IDE?当我尝试您的代码时,Eclipse 会抱怨“未处理的异常类型异常”。这是有道理的,因为Callable接口定义了call()throw 方法Exception。仅仅因为您的实现类声明了一个更受限制的异常类型,调用程序就不能指望它。它希望您捕获异常。

于 2011-05-27T02:10:58.357 回答