You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:25:14