java 使用线程下载多个文件

2022-09-03 03:48:04

我正在尝试使用线程下载与模式匹配的多个文件。该模式可以匹配 1 个、5 个或 10 个差异大小的文件。

为了简单起见,让我们说下载文件的实际代码在downloadFile()方法中,fileNames是与模式匹配的文件名列表。如何使用线程执行此操作。每个线程将仅下载一个文件。是否建议在 for 循环中创建新线程。

for (String name : fileNames){
    downloadFile(name, toPath);
}

答案 1

你真的想使用ExperatorService而不是单个线程,它更干净,可能更高性能,并且将使您能够在以后更轻松地更改内容(线程计数,线程名称等):

ExecutorService pool = Executors.newFixedThreadPool(10);
for (String name : fileNames) {
    pool.submit(new DownloadTask(name, toPath));
}
pool.shutdown();
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// all tasks have now finished (unless an exception is thrown above)

在你的班级中的其他地方定义了实际的工作马:DownloadTask

private static class DownloadTask implements Runnable {

    private String name;
    private final String toPath;

    public DownloadTask(String name, String toPath) {
        this.name = name;
        this.toPath = toPath;
    }

    @Override
    public void run() {
        // surround with try-catch if downloadFile() throws something
        downloadFile(name, toPath);
    }
}

该方法有一个非常令人困惑的名称,因为它“将允许以前提交的任务在终止之前执行”。 声明您需要处理的。shutdown()awaitTermination()InterruptedException


答案 2

是的,您当然可以在 for 循环内创建一个新线程。像这样:

List<Thread> threads = new ArrayList<Thread>();
for (String name : fileNames) {
  Thread t = new Thread() {
    @Override public void run() { downloadFile(name, toPath); }
  };
  t.start();
  threads.add(t);
}
for (Thread t : threads) {
  t.join();
}
// Now all files are downloaded.

例如,在 Executors.newFixedThreadPool(int) 创建的线程池中使用 Executor。