0

如题。我当前的代码对于操作系统来说太过分了,因为它在单独的线程中运行每个 wget 进程,这很好,但是我有将近 15k 文件要下载,所以我想使用线程池来完成这项工作。不幸的是,我必须使用 wget 进行下载过程。

    ExecutorService executor = Executors.newFixedThreadPool(5);
  for(String filename: files) {
        try {
            String encodedFilename = URLEncoder.encode(filename, "UTF-8");
            final String cmd = "wget --no-check-certificate -O " + filename +" " + BipDownloader.bipUrl + encodedFilename;

            Runnable run = new Runnable()
            {
                public void run() {
                    try {
                        System.out.println(cmd);
                        Process process = Runtime.getRuntime().exec(cmd);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }  

                }
            };
            executor.submit(run);
        } catch(IOException e) {
            System.err.println(e.getMessage());
        }    
  }

编辑

更新了源代码以使用线程池,但我的系统在下载过程中仍然不稳定。

4

1 回答 1

2

假设您确实需要使用 wget,您可以使用ExecutorService为您处理线程池:

ExecutorService executor = new FixedThreadPool(100); //pool of 100 threads

...

Runnable r = new Runnable() {

    public void run() {
        try {
            System.out.println(cmd);
            Process process = Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }  
    }
}

executor.submit(r);
  • 池的最佳大小取决于各种因素,最好测试几个数字。100到1000之间的东西应该没问题。
  • 如果您需要监控执行的进度,您可以存储由返回的期货executor.submit,也可以使用 CompletionExecutorService。

编辑

如评论中所述exec,它是非阻塞的,因此理论上,所有进程都可能在它们中的任何一个完成之前启动,即使池的大小是有限的。为了防止你应该等到你的run方法,直到过程完成:

Process process = Runtime.getRuntime().exec(cmd);
int exitVal = process.waitFor();
于 2012-09-11T11:46:21.823 回答