【问题标题】:Why I got an error saying that no one exception is thrown?为什么我收到一个错误说没有抛出任何异常?
【发布时间】:2011-05-27 01:59:52
【问题描述】:

我在一个实现 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
}

【问题讨论】:

标签: java multithreading exception netbeans executor


【解决方案1】:

当您调用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

    } 

}

【讨论】:

  • 如何获取调用方法抛出的异常?
  • @ditkin 不,这不是正确的方法,因为如果你想通知调用者/调用者,在调用中捕获异常不会告诉你如何将它传递给调用者/调用者。你需要让 Future 抓住它。
  • 我在调用方法中捕获异常并返回它并使用 IF 进行威胁。看起来有点奇怪,我会找到另一种方法,但现在,解决我的问题。
  • @Renato Dinhani Conceição 我已经更新了我的答案以提供解决方案。
【解决方案2】:

提交方法不会抛出 SQLException。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 不,这根本无济于事......而且,你不能在没有 catch 的情况下使用 finally。
    • 等等...我可以,是的,我经常这样做。如果您不想在这一步代码中捕获异常,但可以在更全局的范围内捕获异常,则可以这样做。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多