【问题标题】:How to catch exception thrown by another thread in Java? [duplicate]如何捕获Java中另一个线程抛出的异常? [复制]
【发布时间】:2012-05-08 06:40:30
【问题描述】:

我正在使用一个创建自己的线程并引发异常的库。我怎样才能捕捉到那个异常?在下面标记的行上抛出异常:

ResourceDescriptor rd = new ResourceDescriptor();
        rd.setWsType(ResourceDescriptor.TYPE_FOLDER);
        fullUri += "/" + token;
        System.out.println(fullUri);
        // >>> EXCEPTION THROWN ON THE FOLLOWING LINE <<<
        rd.setUriString(fullUri.replaceAll("_", ""));
        try{
            rd = server.getWSClient().get(rd, null);
        }catch(Exception e){
            if(e.getMessage().contains("resource was not found")){
                this.addFolder(fullUri, label, false);
                System.out.println("Folder does not exist, will be added now.");
            }else{
                System.out.println("Error Messages: " + e.getMessage());
            }
        }

【问题讨论】:

  • 如何调用引发异常的方法? (可能是:如何知道抛出异常?)
  • 我已经尝试捕获泛型 Exception 类,但仍然抛出异常。我用谷歌搜索它,它似乎是由我正在使用的库中的另一个线程抛出的。该库通过 Web 服务与 Web 应用程序交互。

标签: java multithreading exception-handling


【解决方案1】:

如果你不能抓住它也许对你有帮助:

如果您有Thread 对象,您可以尝试设置UncaughtExceptionHandler。 看看Thread.setUncaughtExceptionHandler(...)

请向我们提供有关您使用的库以及如何使用它的更多详细信息。

【讨论】:

  • +1 我不知道这个。这比我的回答好。
  • 我对我正在使用的那个库创建的线程没有任何控制权,所以我不能在他们的线程上显式设置未捕获的异常处理程序。我该怎么办?
  • 看看here。这样,您可以获得Thread 对象;)这当然不是一个真正干净的解决方案,但值得一试。
  • 如果我发现异常怎么办?我怎样才能访问它(可能来自代理)?
【解决方案2】:

如果你只有一个Thread 对象,那么就无法捕获任何异常(我假设是RuntimeException)。正确的方法是使用ExecutorService 使用的Future&lt;?&gt; 类,但您无法控制以Thread 开头的代码。

如果您提供Runnable 或者如果您将任何代码注入到库中,那么您可以将它包装在一个类中,该类为您捕获并保存Exception,但前提是异常是在您的代码中或从您正在调用的代码中抛出。类似于以下内容:

final AtomicReference<Exception> exception = new AtomicReference<Exception>();
Thread thread = library.someMethod(new Runnable() {
   public void run() {
      try {
         // call a bunch of code that might throw
      } catch (Exception e) {
         // store our exception thrown by the inner thread
         exception.set(e);
      }
   }
});
// we assume the library starts the thread
// wait for the thread to finish somehow, maybe call library.join()
thread.join();
if (exception.get() != null) {
   throw exception.get();
}

此外,如果您要分叉自己的线程,您还可以设置未捕获的异常处理程序:

thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
   public void uncaughtException(Thread t, Throwable e) {
      // log it, dump it to the console, or ...
   }
});

但是如果库中的线程代码不能被你包裹起来,那就行不通了。如果您编辑问题并显示一些代码并提供更多详细信息,我可以编辑我的问题以提供更好的帮助。

【讨论】:

  • 如果您提供的是Thread 而不是Runnable,您可以覆盖join 方法。这将允许您检查线程是否因异常退出并在加入线程的上下文中重新抛出异常。
  • @artbristol 你是对的。真不幸。
  • 目前我无法控制库,因为它已经编译了。
  • 很好的解释。您能否详细说明使用Future 有何帮助?
  • Future 允许您使用执行器服务,但仍然可以得到池@flow2k 中的线程抛出的异常。
猜你喜欢
  • 2011-06-25
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
  • 2012-01-12
相关资源
最近更新 更多