我正在为我的作业编写代码,我对编写多线程应用程序并不熟悉。我学会了如何打开一个线程并启动它。我最好展示代码。
for (int i = 0; i < a.length; i++) {
download(host, port, a[i]);
scan.next();
}
我上面的代码连接到服务器,打开a.length
多个并行请求。换句话说,下载打开a[i]
连接以在每次迭代时获得相同的内容。但是,我希望我的服务器在i = 0
时完成下载方法,并在下载已打开的线程完成时开始下一次迭代i = 1
。我使用scan.next()来手动停止它,但显然它不是一个很好的解决方案。我怎么能这样做?
编辑:
public static long download(String host, int port) {
new java.io.File("Folder_" + N).mkdir();
N--;
int totalLength = length(host, port);
long result = 0;
ArrayList<HTTPThread> list = new ArrayList<HTTPThread>();
for (int i = 0; i < totalLength; i = i + N + 1) {
HTTPThread t;
if (i + N > totalLength) {
t = (new HTTPThread(host, port, i, totalLength - 1));
} else {
t = new HTTPThread(host, port, i, i + N);
}
list.add(t);
}
for (HTTPThread t : list) {
t.start();
}
return result;
}
在我的HTTPThread中;
public void run() {
init(host, port);
downloadData(low, high);
close();
}
注意:我们的测试Web服务器是经过修改的Web服务器,它获得Range:i-j
,并且在响应中,有i-j
个文件的内容。
答案 0 :(得分:5)
您需要调用正在进行下载的线程的join()
方法。这将导致当前线程等待下载线程完成。 This是关于如何使用加入的好帖子。
如果您想发布下载方法,您可能会获得更完整的解决方案
编辑:
好的,所以在你开始你的线程后,你需要加入它们:
for (HTTPThread t : list) {
t.start();
}
for (HTTPThread t : list) {
t.join();
}
这将停止方法返回,直到所有HTTPThreads都已完成
答案 1 :(得分:1)
创建无限数量的线程以执行无限数量的并行http请求可能不是一个好主意。 (网络套接字和线程都是操作系统资源,需要一些簿记开销,因此在许多操作系统中都会受到配额限制。此外,您正在读取的Web服务器可能不喜欢1000个并发连接,因为他的网络套接字是有限的!)。
您可以使用ExecutorService
轻松控制并发连接数:
List<DownloadTask> tasks = new ArrayList<DownloadTask>();
for (int i = 0; i < length; i++) {
tasks.add(new DownloadTask(i));
}
ExecutorService executor = Executors.newFixedThreadPool(N);
executor.invokeAll(tasks);
executor.shutdown();
这比您自己开发的并发限制更短,更好,因为从当前批次的所有线程完成之前,您的限制将从下一批开始延迟。使用ExceutorService,只要旧任务完成(并且仍有剩余任务),就会开始执行新任务。也就是说,您的解决方案将有1到N个并发请求,直到所有任务都已启动,而ExecutorService将始终有N个并发请求。