简体   繁体   English

java使用线程下载多个文件

[英]java download multiple files using threads

I am trying to download multiple files that matches a pattern using threads. 我正在尝试使用线程下载与模式匹配的多个文件。 The pattern could match 1 or 5 or 10 files of diff sizes. 该模式可以匹配1或5或10个差异大小的文件。

lets say for simplicity sake the actual code that would download the file is in downloadFile() method and fileNames is the list of filenames that match the pattern. 为简单起见,我们可以说下载文件的实际代码是downloadFile()方法,而fileNames是与模式匹配的文件名列表。 How do I do this using threads. 我如何使用线程执行此操作。 Each thread will download only one file. 每个线程只下载一个文件。 Is it advisable to create a new thread inside the for loop. 是否可以在for循环中创建一个新线程。

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

You really want to use an ExecutorService instead of individual threads, it's much cleaner, likely more performant and will enable you to change things more easily later on (thread counts, thread names, etc.): 你真的想使用ExecutorService而不是单独的线程,它更干净,可能性能更高,并且可以让你以后更容易地改变事物(线程数,线程名称等):

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)

And somewhere else in your class define the actual work horse DownloadTask : 在你班级的其他地方定义实际工作马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);
    }
}

The shutdown() method has a very confusing name, because it "will allow previously submitted tasks to execute before terminating". shutdown()方法有一个非常混乱的名称,因为它“将允许先前提交的任务在终止之前执行”。 awaitTermination() declares an InterruptedException you need to handle. awaitTermination()声明您需要处理的InterruptedException

Yes, you certainly could create a new thread inside the for-loop. 是的,你当然可以在for循环中创建一个新线程。 Something like this: 像这样的东西:

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.

You should also consider using an Executor , for example, in a thread pool created by Executors.newFixedThreadPool(int) . 你也应该考虑使用Executor ,例如,通过创建一个线程池Executors.newFixedThreadPool(int)

Yes you can create the Threads inline. 是的,您可以创建内联线程。

for (final String name : fileNames){
    new Thread() {
       public void run() {
           downloadFile(name, toPath);
       }
    }.start();
}

Use Executor , Try this. 使用Executor ,试试这个。

ExecutorService  exec= Executors.newCachedThreadPool()
for (String name : fileNames){
 exec.submit(new Runnable()
 {
  public void run()
  {
    downloadFile(name, toPath);
  }
 });
}

If you want say three download running concurrently, you can use: 如果你想同时说三个下载运行,你可以使用:

Executors.newFixedThreadPool(3)

All the Above mentioned approach creates Threads but the actual Concurreny is not achieved. 所有上面提到的方法都创建了Threads但实际的Concurreny却没有实现。

ExecutorService pool = Executors.newFixedThreadPool(5);
final File folder = new File("YOUR_FILES_PATH");
int l = folder.listFiles().length;
System.out.println("Total Files----"+folder.listFiles().length);
long timeStartFuture = Calendar.getInstance().getTimeInMillis();
    pool.execute(new DownloadFile(folder,0,l/2));
    pool.execute(new DownloadFile(folder,(l/2),l));
    pool.shutdown();
    try {
        pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    long timeEndFuture = Calendar.getInstance().getTimeInMillis();
    long timeNeededFuture = timeEndFuture - timeStartFuture;
    System.out.println("Parallel calculated in " + timeNeededFuture + " ms");

The above program is used to achieve concurreny and please modify as per your requirement. 以上程序用于实现concurreny,请根据您的要求进行修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM