java java使用线程下载多个文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7502718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java download multiple files using threads
提问by user373201
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. 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.
让我们说为简单起见,下载文件的实际代码在 downloadFile() 方法中,fileNames 是与模式匹配的文件名列表。我如何使用线程来做到这一点。每个线程将只下载一个文件。是否建议在 for 循环内创建一个新线程。
for (String name : fileNames){
downloadFile(name, toPath);
}
回答by Philipp Reichart
You really want to use an ExecutorServiceinstead 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". awaitTermination()
declares an InterruptedException
you need to handle.
该shutdown()
方法的名称非常混乱,因为它“将允许在终止之前执行先前提交的任务”。awaitTermination()
声明一个InterruptedException
你需要处理的。
回答by maerics
Yes, you certainly could create a new thread inside the for-loop. Something like this:
是的,您当然可以在 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.
You should also consider using an Executor
, for example, in a thread pool created by Executors.newFixedThreadPool(int)
.
Executor
例如,您还应该考虑在由Executors.newFixedThreadPool(int)
.
回答by Bitmap
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)
回答by Garrett Hall
Yes you can create the Threads inline.
是的,您可以内联创建线程。
for (final String name : fileNames){
new Thread() {
public void run() {
downloadFile(name, toPath);
}
}.start();
}
回答by ihappyk
All the Above mentioned approach creates Threads but the actual Concurreny is not achieved.
上面提到的所有方法都创建了线程,但没有实现实际的并发。
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.
以上程序用于实现并发,请根据您的要求进行修改。