Подтвердить что ты не робот

Java скачать несколько файлов с помощью потоков

Я пытаюсь загрузить несколько файлов, которые соответствуют шаблону, используя потоки. Шаблон может соответствовать 1 или 5 или 10 файлам разностей размеров.

позволяет просто сказать, что фактический код, который будет загружать файл, находится в методе DownloadFile(), а fileNames - это список имен файлов, соответствующих шаблону. Как это сделать с помощью потоков. Каждый поток будет загружать только один файл. Целесообразно создать новый поток внутри цикла for.

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

Ответ 1

Вы действительно хотите использовать 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)

И где-нибудь еще в вашем классе определите фактическую рабочую лошадь 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.

Вы также должны рассмотреть возможность использования Executor, например, в пуле потоков, созданном Executors.newFixedThreadPool(int).

Ответ 3

Да, вы можете создать потоки inline.

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

Ответ 4

Используйте Executor, попробуйте это.

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

Если вы хотите, чтобы три загрузки выполнялись одновременно, вы можете использовать:

Executors.newFixedThreadPool(3)

Ответ 5

Весь вышеупомянутый подход создает потоки, но фактический 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");

Вышеупомянутая программа используется для достижения согласованности и, пожалуйста, измените ее согласно вашему требованию.