我们有一个 Web 应用程序需要通过 http 从合作伙伴站点导入 10-20 张图像。如果我有一个代表我要下载的网址的字符串列表,是否有人建议如何尽快下载它们?
我可以将它们放在一个 for 循环中,但如果有一种简单的方法可以并行化它,它可能对最终用户有好处。我想避免使用直接的 Java 线程,尽管执行器框架可能是个好主意。
有任何想法吗?
我们有一个 Web 应用程序需要通过 http 从合作伙伴站点导入 10-20 张图像。如果我有一个代表我要下载的网址的字符串列表,是否有人建议如何尽快下载它们?
我可以将它们放在一个 for 循环中,但如果有一种简单的方法可以并行化它,它可能对最终用户有好处。我想避免使用直接的 Java 线程,尽管执行器框架可能是个好主意。
有任何想法吗?
这是我对Resty的看法。(免责声明:我是 Resty 的作者)下载命令行中给出的所有 URL 并打印出文件名。
package us.monoid.web.parallel;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import us.monoid.web.Resty;
public class Downloader {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Callable<File>> tasks = new ArrayList<Callable<File>>(args.length);
for (final String url : args) {
tasks.add(new Callable<File>() {
public File call() throws Exception {
return new Resty().bytes(url).save(File.createTempFile("img", ".png"));
}
});
}
List<Future<File>> results = pool.invokeAll(tasks);
for (Future<File> ff : results) {
System.out.println(ff.get());
}
}
}
Executor 框架正是您想要的。特别是 ExecutorCompletionService。使用它,您将能够以任何顺序快速提交请求。然后,您将完全按照它们完成的方式检索它们(而不是提交顺序)。
使用 Resty Library 可以下载自定义名称的图片如下
try {
ExecutorService pool = Executors.newFixedThreadPool(Names.size());
List<Callable<File>> tasks = new ArrayList<Callable<File>>(Names.size());
for (final String url : Urls) {
tasks.add(new Callable<File>() {
public File call() throws Exception {
File f=new File(directory+iimage);
return new Resty().bytes(url).save(f);
}
});
i++;
}
i=0;
List<Future<File>> results = pool.invokeAll(tasks);
for (Future<File> ff : results) {
System.out.println(ff.get());
}
} catch (ExecutionException e) {
// TODO Auto-generated catch block
fails++;
e.printStackTrace();
}