我正在克隆大量GitHub项目样本进行实证研究。我假设用一些并发性下载80,000个项目会更快,但下载量很大。
如何启动~1,000个进程,然后在每个进程完成后再启动另一个进程?或者,还有其他方法我应该这样做吗?以快于连续的速度下载这么多对GitHub的服务器有害吗?
到目前为止,这是相关的代码:
DatabaseMetaData
工人:
// 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();
答案 0 :(得分:3)
这对github的服务器来说很糟糕,但对你的性能来说却更糟糕。尝试5个左右而不是1000个。要将代码限制为X个并行线程,可以使用池:
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();
也可以在没有闩锁的情况下工作,因为您可以通过例如等待池空闲。
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
答案 1 :(得分:0)
您可以尝试Java 8和parallelStream来进行多线程下载
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();
}
}
);
答案 2 :(得分:0)
对于像这样的简单任务,不需要使用多线程和自定义Java代码。特别是因为每个线程只使用CLI生成外部进程。它过度工程化,你可以通过使用更简单的东西来更快地完成工作。
看起来您可能已经有一个文件,其中包含您要克隆的所有项目的网址。我会在文本编辑器(Sublime Text)中使用一些命令将git clone --depth=1
添加到每行的开头,将&
添加到结尾(这会异步运行命令)。如果你的文本编辑器不能轻易做到这一点,那么一个bash / awk / perl / Ruby / Python / etc脚本可以在不超过几行的情况下完成。
然后你的URL列表变成......一个有效的shell脚本,它将并行克隆所有的repos!你可以这样运行它。
请注意,虽然运行并行下载将帮助您,但1000太多了。您可以尝试使用该数字,但您可能会发现同时运行超过20个也无济于事。