2016-06-27 3 views
1

私は経験豊富な研究のためにGitHubプロジェクトの大きなサンプルをクローンしています。私は80,000のプロジェクトをいくらかの並行性でダウンロードする方が速いと思っていますが、それはダウンロードするのが大変です。Javaで同時に80,000ダウンロードを取得するにはどうすればよいですか?

どのようにして〜1000プロセスを開始し、それぞれが終了した後に別のプロセスを開始できますか?あるいは、これについて別の方法で行くべきですか? GitHubのサーバーでは、これをずっと速い速度でダウンロードすることは悪いことでしょうか?

ここでは、関連するコードは、これまでのところです:

// Create a CountDownLatch that will only reach 0 when all repositories 
// have been downloaded 
CountDownLatch doneSignal = new CountDownLatch(numberOfRepositories); 

// Start the download for each git repository 
for (String URL : gitURLs) 
{ 
    new Thread(new Worker(doneSignal, URL)).start(); 
} 

doneSignal.await(); 

ワーカー:

public class Worker implements Runnable 
{ 
    private final CountDownLatch doneSignal; 
    private final String URL; 

    Worker (CountDownLatch doneSignal, String URL) 
    { 
     this.doneSignal = doneSignal; 
     this.URL = URL; 
    } 

    @Override 
    public void run() 
    { 
     try 
     { 
      // Run the command line process to download 
      ProcessBuilder pb = 
       new ProcessBuilder("git", "clone", "--depth=1", URL, "projects/" + getProjectName(URL)); 
      Process p = pb.start(); 
      p.waitFor(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 

     doneSignal.countDown(); 
    } 
} 
+0

とにかく、私はGithubのサーバーが同じIPから同時に多くのDLを起動させないと思う。 –

+0

ええ、私は願っていません。 – Andrew

答えて

3

それはgithubののサーバーに悪いですが、それはあなたのパフォーマンスをさらに悪化です。あなたが経由アイドルなどになるためにプールを待つことができるので、ラッチなし

CountDownLatch doneSignal = new CountDownLatch(numberOfRepositories); 
// Start the download for each git repository 
ExecutorService pool = Executors.newFixedThreadPool(5); 
for (String URL : gitURLs) { 
    pool.execute(new Worker(doneSignal, URL)); 
} 
pool.shutdown(); 
doneSignal.await(); 

も動作します:あなたは、プールを使用することができ、X並列スレッドにコードを制限するには、多分5かそこらの代わりに1000をお試しください

pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
0

あなたはこのような単純なタスクのためのマルチスレッドとカスタムJavaコードを使用する必要はありません

List<String> gitURLs = new ArrayList<>(); 

    gitURLs.parallelStream().forEach(
     URL -> 
     { 
      try 
      { 
       // Run the command line process to download 
       ProcessBuilder pb = 
         new ProcessBuilder("git", "clone", "--depth=1", URL, "projects/" + getProjectName(URL)); 
       Process p = pb.start(); 
       p.waitFor(); 
      } 
      catch (Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    ); 
0

ダウンロードをマルチスレッドのJava 8とparallelStreamを試すことができます。特に、各スレッドはCLIを使用して外部プロセスを生成するだけです。それはオーバーエンジニアリングなので、より簡単なものを使用することで、より迅速に作業を進めることができます。

あなたが既にクローンしたいすべてのプロジェクトのURLを持つファイルを持っているようです。テキストエディタ(Sublime Text)でいくつかのコマンドを使用して、各行の先頭にgit clone --depth=1を追加し、最後に&(これはコマンドを非同期に実行します)を追加します。あなたのテキストエディタがそれを簡単に行うことができない場合、少しのbash/awk/Perl/Ruby/Python/etcスクリプトでは数行しかできません。

あなたのURLのリストは、有効なシェルスクリプトになります。これは、すべてのreposを並行してクローンします!そして、それをそのまま実行することができます。

パラレルダウンロードを実行している間にが役に立ちますが、1000は多すぎます。あなたはその数を試すことができますが、同時に20以上を走らせることは助けになりません。

関連する問題