簡體   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