我有一个包含100万个文件名的列表,我必须从S3
下载。目前我正在逐个下载每个文件(下面的for循环),下载完成大约需要4天。
for (String fileName : Files) {
InputStream is = null;
try {
is = m_S3.downloadFile(fileName); // m_s3 is a wrapper around AmazonS3 client
m_localDisk.createFile(fileName, is); // m_localDisk is an interface for local disk storage.
}
catch (Exception e) {
System.out.println("Exception happened");
}
finally {
is.close();
}
}
由于S3
允许并行连接,我计划平行下载。我怎么能在Java
中做到这一点?我在C
中使用Pthread
做了类似的事情,我只是将输入和委托线程与其上下文中的输入的不同部分分开。我可以在Java
中做到这一点,但我相信有更好,更高级别的方法可以做到这一点。
我考虑过使用parallelStreams
之类的东西,但因为它只是使用了管道机制,我认为它不会给我带来太大的改进 - 只有一个到S3
的网络连接将在一段时间。
答案 0 :(得分:1)
使用parallelStream
可能是解决此问题的最简单方法
默认的AmazonS3Client最多可处理50个并发连接,但您可以采用不同的方式进行配置。
默认情况下,parallelStream()
使用共享系统线程池,并使用numOfProcessors -1
个线程,下面的方法创建自己的线程池,您可以根据自己的需要调整大小,加上长时间运行阻止任务不会干扰系统池上运行的其他事情。
List<String> fileNames = ...
ForkJoinPool forkJoinPool = new ForkJoinPool(4);
forkJoinPool.submit(()-> {
fileNames.parallelStream().forEach(fileName -> {
try(InputStream is = m_S3.downloadFile(fileName)) {
m_localDisk.createFile(fileName, is);
} catch (IOException e) {
e.printStackTrace();
}
});
}).get();