java下载使用线程的多个文件
我想下载使用线程匹配模式的多个文件。该模式可以匹配1或5或10个差异文件。java下载使用线程的多个文件
可以说为了简单起见,下载文件的实际代码是在downloadFile()方法中,fileNames是与该模式匹配的文件名列表。我如何使用线程来做到这一点。每个线程只会下载一个文件。建议在for循环中创建一个新线程。
for (String name : fileNames){
downloadFile(name, toPath);
}
你真的想用一个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
。
是的,你可以创建内联线程。
for (final String name : fileNames){
new Thread() {
public void run() {
downloadFile(name, toPath);
}
}.start();
}
是的,你当然可以在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个文件。你有一个使用Executor – user373201
@ user373201的例子:按照我提供给'Executors.newFixedThreadPool(int)'的链接并查看@Phillip Reichart的答案。 – maerics
使用Executor,试试这个。
ExecutorService exec= Executors.newCachedThreadPool()
for (String name : fileNames){
exec.submit(new Runnable()
{
public void run()
{
downloadFile(name, toPath);
}
});
}
如果你想要说的三个下载同时运行,你可以使用:
Executors.newFixedThreadPool(3)
现在它阻塞while execute()'Runnable',你打算叫'exec.submit()':) –
@Philipp Reichart你真的知道你在说什么吗?执行时阻止什么?听着布鲁夫!当你不知道你在说什么时,避免标记人。 – Bitmap
是的,我确实曾经被这一次咬过。 ['Execute.execute()'](http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/Executor.html#execute(java.lang.Runnable))may “...在Executor实现的判断下,在新线程,共用线程或调用线程**中执行。“你真的想声明变量为'ExecutorService'并使用['submit()'](http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html#提交(java.lang.Runnable))。 –
所有上述提到的方法创建线程,但实际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");
上述程序用于实现并发性,并请修改按您的要求。
这需要'downloadFile()'方法在'DownloadTask'(我的推荐)中定义,或者在外部声明'static'。 –
'@Philipp Reichart'发布'shutdown'后,新的下载任务将不会被游泳池接受。如果我是你,我会避免这种情况。 – Bitmap
这是一个没有问题的问题,因为在这种情况下关闭后没有任何新任务添加到池中。第一个代码片段应该存在于一个方法中,并在每次调用时创建一个新池。 –