0

問題のように。私の現在のコードは、すべてのwgetプロセスを個別のスレッドで実行するためOSにとってはやり過ぎです。これは問題ありませんが、ダウンロードするファイルが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 に答える