简体   繁体   English

多线程与 Java,如何停止?

[英]Multi-threading with Java, How to stop?

I am writing a code for my homework, I am not so familiar with writing multi-threaded applications.我正在为我的家庭作业编写代码,我对编写多线程应用程序不太熟悉。 I learned how to open a thread and start it.我学会了如何打开一个线程并启动它。 I better show the code.我最好显示代码。

 for (int i = 0; i < a.length; i++) {
     download(host, port, a[i]);
     scan.next();                        
 }

My code above connects to a server opens a.length multiple parallel requests.我上面的代码连接到服务器会打开a.length多个并行请求。 In other words, download opens a[i] connections to get the same content on each iteration.换句话说,下载打开a[i]连接以在每次迭代中获取相同的内容。 However, I want my server to complete the download method when i = 0 and start the next iteration i = 1 , when the the threads that download has opened completes.但是,我希望我的服务器在i = 0时完成下载方法,并在下载已打开的线程完成时开始下一次迭代i = 1 I did it with scan.next() to stop it by hand but obviously it is not a nice solution.我使用 scan.next() 手动停止它,但显然这不是一个好的解决方案。 How can I do that?我怎样才能做到这一点?

Edit:编辑:

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;
}

And In my HTTPThread;在我的 HTTPThread 中;

 public void run() {
     init(host, port);
     downloadData(low, high);
     close();
 }

Note: Our test web server is a modified web server, it gets Range: ij and in the response, there is contents of the ij files.注意:我们的测试 web 服务器是一个修改后的 web 服务器,它得到 Range: ij并且在响应中,有ij文件的内容。

You will need to call the join() method of the thread that is doing the downloading.您需要调用正在下载的线程的join()方法。 This will cause the current thread to wait until the download thread is finished.这将导致当前线程等待,直到下载线程完成。 This is a good post on how to use join.是一篇关于如何使用加入的好帖子。

If you'd like to post your download method you will probably get a more complete solution如果您想发布您的下载方法,您可能会获得更完整的解决方案

EDIT:编辑:

Ok, so after you start your threads you will need to join them like so:好的,所以在你开始你的线程后,你需要像这样加入它们:

for (HTTPThread t : list) {
    t.start();
}
for (HTTPThread t : list) {
    t.join();
}

This will stop the method returning until all HTTPThreads have completed这将停止方法返回,直到所有 HTTPThreads 完成

It's probably not a great idea to create an unbounded number of threads to do an unbounded number of parallel http requests.创建无限数量的线程来执行无限数量的并行 http 请求可能不是一个好主意。 (Both network sockets and threads are operating system resources, and require some bookkeeping overhead, and are therefore subject to quotas in many operating systems. In addition, the webserver you are reading from might not like 1000s of concurrent connections, because his network sockets are finite, too.). (网络 sockets 和线程都是操作系统资源,需要一些记账开销,因此在许多操作系统中受到配额限制。另外,您正在读取的网络服务器可能不喜欢 1000 的并发连接,因为他的网络 sockets 是也是有限的。)。

You can easily control the number of concurrent connections using an ExecutorService :您可以使用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();

This is both shorter and better than your homegrown concurrency limit, because your limit will delay starting with the next batch until all threads from the current batch have completed.这比您自己开发的并发限制更短且更好,因为您的限制将延迟从下一个批次开始,直到当前批次中的所有线程都完成。 With an ExceutorService, a new task is begun whenever an old task has completed (and there are still tasks left).使用 ExecutorService,只要旧任务完成(并且仍有任务剩余),新任务就会开始。 That is, your solution will have 1 to N concurrent requests until all tasks have been started, whereas the ExecutorService will always have N concurrent requests.也就是说,在所有任务启动之前,您的解决方案将有 1 到 N 个并发请求,而 ExecutorService 将始终有 N 个并发请求。

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

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