简体   繁体   中英

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. In other words, download opens a[i] connections to get the same content on each iteration. 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 did it with scan.next() to stop it by hand but obviously it is not a nice solution. 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;

 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.

You will need to call the join() method of the thread that is doing the downloading. 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

It's probably not a great idea to create an unbounded number of threads to do an unbounded number of parallel http requests. (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.).

You can easily control the number of concurrent connections using an 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). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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