2017-06-01 74 views
1

的StackOverflowError遞歸性我得到StackOverflowError異常報告同時呼籲這個遞歸方法:固定使用的Runnable

private void downloadFiles(int index) { 
    if (index < totalFiles) { 
     downloadSingleFile(index, new DownloadCallback() { 
      @Override 
      public void onSuccess(String filePath) { 
       downloadFiles(index + 1); 
      } 
     }); 
    } 
} 

我想問如果我用一個Runnable像這樣:

int index = 0; 
handler = new Handler(); 
Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
     downloadFiles(); 
    } 
}; 
handler.post(runnable); 

private void downloadFiles() { 
    if (index < totalFiles) { 
     downloadSingleFile(index, new DownloadCallback() { 
      @Override 
      public void onSuccess(String filePath) { 
       index ++; 
       handler.post(runnable); 
      } 
     }); 
    } 
} 

這會不會是一個遞歸,以及拋出異常? 謝謝

+0

你有至少通過堆棧跟蹤讀?它應該很容易地告訴你哪一行導致異常。閱讀https://stackoverflow.com/questions/214741/what-is-a-stackoverflowerror –

+0

我已閱讀它,但它告訴我,如果我的解決方案使用runnable將修復或不。 – GeniDeveloper

回答

1

你當前使用的遞歸排序失敗了使用多線程的目的。目前,您只能創建一個將輸入downloadFiles()的單個線程,然後遞歸嘗試下載每個可用的文件。這不是真正的多線程,它是遞歸單線程。這種方法有幾個缺點。首先,你沒有利用多線程並行工作的能力。其次,由於每個後續的遞歸調用都依賴於前一個成功的調用,因此您試圖以串行方式下載文件。如果一個給定的文件下載失敗了,它會打破遞歸鏈的其餘部分。

更好的方法是爲每個文件下載生成一個新的線程。這將允許您使用多線程的能力來並行分割任務,並且即使一個線程遇到一些問題也可以繼續進行。

看一看下面的代碼段用於對如何處理你的問題的想法:

public class FileDownloader implements Runnable { 
    private index; 

    public FileDownloader(int index) { 
     this.index = index; 
    } 

    public void run() { 
     downloadSingleFile(index, new DownloadCallback() { 
      @Override 
      public void onSuccess(String filePath) { 
       // this may no longer be needed 
      } 
     }); 
    } 
} 

// use a thread pool of size 5 to handle your file downloads 
ExecutorService executor = Executors.newFixedThreadPool(5); 
for (int index=0; index < totalFiles; ++index) { 
    Runnable r = new FileDownloader(index); 
    executor.execute(r); 
} 

// shut down the thread pool executor and wait for it to terminate 
executor.shutdown(); 
while (!executor.isTerminated()) { 
} 
+0

如果你不使用有限的線程池,如果源包含很多文件,你將很快耗盡線程資源。 –

+0

@JimGarrison我更新了我的答案以使用線程池。坦率地說,我並沒有做太多的多線程Java工作,但是OP對遞歸的使用與多線程應該做的很遠,所以我想我會試着回答這個問題。 –

+0

你的回答在並行下載文件方面很有用,但是並沒有回答我的問題,我的問題是:在這種方式下使用runnable它仍然是一個遞歸或不是? – GeniDeveloper