IAmSoCool
IAmSoCool

Reputation: 13

Java requests in thread

I am stuck in this problem, I am using thread and http request to fetch data, but my method always returns either empty string or response of last request. Here is my code:

static String a = "";
public static String request(String request) {
    new Thread(() -> {
        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(request).openConnection();
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line, text = "";
            while((line = br.readLine()) != null) {
                text = line;
            }
            br.close();
            a = text;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }).start();
    return a;
}

Upvotes: 1

Views: 1671

Answers (2)

Stephen C
Stephen C

Reputation: 718768

There is not context in your Question to be sure that this is the problem, but one issue with your code is that you are not waiting for the thread to finish before returning the value of a. So, you are probably returning the contents of a before the thread has stored anything in it.

In fact, this code is all a bit wrong-headed. If you want request(String) to return the value retrieved from the server, the request calll can't complete until the after you have retrieved the data. This is unavoidably synchronous. Using a Thread to do the retrieving is actually achieving nothing.

(Using join() as suggested "fixes" the symptom, but doesn't the pointless of using a thread here.)

If you want this to be asynchronous, you could change request to return a Future<String> that the caller can use to get hold of the retrieved value at a later time.

And it would be simpler and (probably) more efficient if you used an Executor rather than creating once-time-use threads for each "request".

Upvotes: 2

Rajan Kali
Rajan Kali

Reputation: 12953

It is an asynchronous call, so your return statement wont wait until thread executes as it non blocking, you can use call back to get the string when and ever it is ready

interface ResponseCallBack{
   void onResponse(String a);
   void onError(Exception e);
}

then pass this interface while calling your method

public static void request(String request, ResponseCallBack responseCallBack) {
    new Thread(() -> {
        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(request).openConnection();
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line, text = "";
            while((line = br.readLine()) != null) {
                text = line;
            }
            br.close();
            responseCallBack.onResponse(text);
        } catch (IOException e) {
            e.printStackTrace();
            responseCallBack.onError(e);
        }
    }).start();
}

Then you can consume it using

request("", new ResponseCallBack() {
        @Override
        public void onResponse(String a) {
            //here string will be available
        }

        @Override
        public void onError(Exception e) {
            //error in case something failed
        }
});

Upvotes: 3

Related Questions