Java 个线程中的请求

Java requests in thread

我陷入了这个问题,我正在使用线程和 http 请求来获取数据,但我的方法总是 returns 要么是空字符串,要么是最后一个请求的响应。这是我的代码:

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

你的问题中没有上下文可以确定这是问题所在,但你的代码有一个问题是你没有在等待线程完成之前 returning a。因此,您 可能 return正在 a 的内容 线程在其中存储任何内容之前。

其实这段代码有点偏题了。如果您想要 request(String) 到 return 从服务器检索的值,则 request 调用在您检索到数据后才能完成。这不可避免地是同步的。使用 Thread 进行检索实际上是一无所获。

(按照建议使用 join() 可以“修复”症状,但在这里使用线程并不是没有意义的。)

如果您希望它是异步的,您可以将 request 更改为 return 一个 Future<String> 调用者可以在以后使用它来获取检索到的值。

如果您使用 Executor 而不是为每个“请求”创建一次性使用的线程,它会更简单并且(可能)更有效。

这是一个异步调用,因此您的 return 语句不会等到 thread 执行,因为它是非阻塞的,您可以随时使用回调来获取 string准备就绪

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

然后在调用你的方法时传递这个接口

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

然后您可以使用

来消费它
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
        }
});