繁体   English   中英

在Java中,如何捕获从子线程引发的异常,然后从父线程再次引发异常

[英]In java how can I catch an exception thrown from child thread and then throw it again from the parent thread

我目前有以下示例代码,我正在尝试将OutputStream转换为InputStream,我从http://blog.ostermiller.org/convert-java-outputstream-inputstream的 Method 2中得到了这个想法

但是我的问题是,save方法可能会引发IOException,我想捕获该异常并将其作为该getInputStream方法的一部分重新抛出。

我正在尝试将save(out)引发的IOException包装为运行时异常,但是我知道父线程无法捕获此运行时异常。 因此,我坚持这一点,谁能为我指出一些方向?

public InputStream getInputStream() throws IOException {
    PipedInputStream in = new PipedInputStream();
    PipedOutputStream out = new PipedOutputStream(in);
    Thread t = new Thread(new Runnable() {
        public void run () {
            try {
                save(out); // this save method can throw IOException
            } catch (IOException e) {
                throw new RuntimeException("Failed to save entries to output stream", e);
            }
        }
    });
    t.start();

    return in;
}


private void save(OutputStream out) throws IOException {...}  

我已经阅读了如何从线程中捕获异常,但是觉得我的问题还是不一样,因为我想在父线程中重新抛出该异常,上面的问题解决了仅捕获异常的问题

尽管所有导致未捕获的异常处理程序和类似内容的注释都是正确的,但我想将这个答案作为替代发布。

您可以使用ExecutorService,该服务将返回Future,然后在获取结果时可以捕获ExecutionException,如下所示(直接在此处键入,可能需要进行一些验证):

ExecutorService pool = Executors.newFixedThreadPool(1);
Future result = pool.submit(this::save);
result.get(); // will throw ExecutionException

但是我的问题是,save方法可能会引发IOException,我想捕获该异常并将其作为该getInputStream方法的一部分重新抛出。

您无法执行此操作,因为在getInputStream()返回很久之后执行save()的后台线程中可能引发异常。

如果save()可能由于其PipedOutputStreamIOException以外的原因而引发异常,并且您想将有关该故障的一些信息传达给正在从PipedInputStream读取的线程,则将Callable提交给ExecutorService可能是正确的方法。 这种情况的一个例子是save()查询数据库,并将结果写到流中。 如果查询失败, SQLException 在读取该流的线程中记录该SQLException 读取线程可以读取PipedInputStream ,然后检查从将任务提交给ExecutorService收到的Future ,以查看其是否异常完成。

但是,如果您不需要save()引发的异常中的任何信息,而只想在从相应的PipedInputStream读取的线程中引发异常,则只需让后台线程死亡即可。 尝试从其PipedInputStream读取时,这将在主线程中引发“中断管道” IOException

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM