Why won't the program exit?

Viplav Kumar :

Okay, so I was trying to convert a blocking network request to a non-blocking request. The library that I'm using for network I/O does provide functions to make asynchronous HTTP calls, but anyways, for the sake of experiments, I tried to do it this way:

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.GetRequest;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class TestExecutorService {
    private static final ExecutorService executor = Executors.newSingleThreadExecutor();
    static volatile Thread innerThread;

    public static void asyncGet (String url) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                innerThread = Thread.currentThread();
                GetRequest request = Unirest.get(url);
                try {
                    HttpResponse <String> response = request.asString();
                    System.out.println(response.getBody());
                    Unirest.shutdown();
                } catch (UnirestException exc) {
                    exc.printStackTrace();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        });
    }
}
public class Main {
    public static void main(String[] args) {
        TestExecutorService.asyncGet("https://stackoverflow.com");
        System.out.println("We're already here!");

        try {
            // Delay so that executor service's thread object could be
            // ...assigned to static variable innerThread
            Thread.sleep(100);
            TestExecutorService.innerThread.join();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

I'm not a pro programmer and an absolute beginner when it comes to concurrency, and even I could tell that this piece of code can be improved, at least bit (one of those feelings you have as a beginner when you know something is wrong, but not sure what is). Anyways, what confuses me about the code above is that the program does not terminate. I didn't expect that to happen. I read a bit about Executors.singleThreadExecutor and I have an idea that if the inner thread dies for some reason, it creates a new thread and "transports" the state safely to the newly created thread. I've no clue why the program does not terminate though. Can someone give some hints?

Please note that the code provided here will not be used in production environments. I wrote this just for practice.

gaborsch :

You are mixing two patterns.

If you are using executors, you don't need to join. That thread was started by a system thread, not your main thread. It is not your child thread, actually you cannot join it. Just fire and forget.

If you create the thread yourself, then run it, you should join it. Then the child thread is yours.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=159503&siteId=1