Java多线程中Future.get()返回null问题排查求助
问题:Java多线程调用API后Future.get()返回null
我首次尝试在Java中使用多线程,需求是批量拉取多个月份的API数据,经过几次尝试后卡在以下代码处,调用Future.get()时所有结果均返回null,请问有人能解释原因吗?
class StyleThreadDemo implements Callable<String>{ private Integer n; public StyleThreadDemo(int a){ this.setN(a); } public String callApi() throws Exception { String output=null; try { URL url = new URL("https://api.publicapis.org/entries"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept", "application/json"); if (conn.getResponseCode() != 200) { throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode()); } BufferedReader br = new BufferedReader(new InputStreamReader( (conn.getInputStream()))); System.out.println("Data starting coming .... \n"); while ((output = br.readLine()) != null) { System.out.println("result "+ n ); } conn.disconnect(); }catch(Exception e) { e.printStackTrace(); } return output; } @Override public String call() throws Exception { String s=callApi(); return s; } public Integer getN() { return n; } public void setN(Integer n) { this.n = n; } } public class StyleThread { public static void shutdownAndAwaitTermination(ExecutorService executorService) { executorService.shutdown(); try { if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { executorService.shutdownNow(); } } catch (InterruptedException ie) { executorService.shutdownNow(); Thread.currentThread().interrupt(); } } public static void main(String[] args) throws Exception { StyleThread styleThread = new StyleThread(); ExecutorService pool = Executors.newFixedThreadPool(30); int n = 5; // Number of threads List<StyleThreadDemo> tasks= new ArrayList<StyleThreadDemo>(); // List<Future<String>> futures = new ArrayList<>(); for (int i = 0; i < n; i++) { // Future<String> result= pool.submit(new StyleThreadDemo(i)); // futures.add(result); tasks.add(new StyleThreadDemo(i)); System.out.println("task added "+i); } List<Future<String>> futures=pool.invokeAll(tasks); shutdownAndAwaitTermination(pool); for (Future<String> f : futures) { System.out.println("printing :+f.get()); } } }
问题原因
核心问题出在callApi()方法的返回值逻辑上:
- 你初始化
String output=null;,随后在while ((output = br.readLine()) != null)循环中,每次读取一行数据赋值给output,仅打印线程编号但未保留数据。 - 当流读取到末尾时,
br.readLine()返回null,此时output被赋值为null,循环终止。 - 最终返回的就是这个已经变为null的
output,因此所有Future.get()调用都拿到null。
另外代码存在语法错误:System.out.println("printing :+f.get());缺少一个闭合双引号,正确写法应为System.out.println("printing :" + f.get());。
修复方案
若要获取完整的API响应内容,需要将读取到的每一行数据拼接起来,而非仅保留最后一行(最后还变为null)。修改callApi()方法如下:
public String callApi() throws Exception { StringBuilder responseBuilder = new StringBuilder(); try { URL url = new URL("https://api.publicapis.org/entries"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Accept", "application/json"); if (conn.getResponseCode() != 200) { throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode()); } BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); System.out.println("Data starting coming .... \n"); String line; while ((line = br.readLine()) != null) { responseBuilder.append(line); System.out.println("result " + n); } conn.disconnect(); } catch (Exception e) { e.printStackTrace(); return null; // 异常场景可根据需求返回特定值或抛出异常 } return responseBuilder.toString(); }
同时修正main方法中的打印语句:
for (Future<String> f : futures) { System.out.println("printing :" + f.get()); }
修改后即可正确获取API的完整响应内容,而非null。
内容的提问来源于stack exchange,提问作者Manish Meena
相关产品推荐
相关产品推荐

