Java多线程Future.get()方法获取结果为null的解决方案

Java多线程Future.get()方法获取结果为null的解决方案

本文旨在解决Java线程编程中使用`Future.get()`方法时,遇到的结果为NULL的问题。通过分析代码示例,解释了导致该问题的原因,并提供了使用StringBuilder累计读取结果的解决方案,确保从API接口获取的数据能够正确返回。

java多线程编程中,Future接口用于表示异步计算的结果。当你使用ExecutorService提交任务时,会返回一个Future对象,你可以通过调用Future.get()方法来获取任务的执行结果。然而,有时Future.get()会返回null,这通常是因为任务的返回值在某些情况下没有正确设置。

问题分析

在提供的代码示例中,问题出在StyleThreadDemo类的callApi()方法中。该方法通过HttpURLConnection从API接口读取数据,并将读取到的数据赋值给output变量。关键代码如下:

立即学习Java免费学习笔记(深入)”;

while ((output = br.readLine()) != null) {     System.out.println("result "+ n ); } return output;

这段代码使用BufferedReader逐行读取API的响应,并在循环中打印一些信息。但是,当循环结束时,output变量的值为null,因为循环的退出条件是br.readLine()返回null。因此,callApi()方法最终返回null,导致Future.get()也返回null。

解决方案

为了解决这个问题,我们需要在循环中累积读取到的数据,并在循环结束后返回累积的结果。可以使用StringBuilder来实现:

Java多线程Future.get()方法获取结果为null的解决方案

稿定AI文案

小红书笔记、公众号、周报总结、视频脚本等智能文案生成平台

Java多线程Future.get()方法获取结果为null的解决方案45

查看详情 Java多线程Future.get()方法获取结果为null的解决方案

public String callApi() throws Exception {     StringBuilder sb = new StringBuilder();     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 );             sb.append(output);         }          conn.disconnect();     }catch(Exception e) {         e.printStackTrace();     }     return sb.toString(); }

在这个修改后的版本中,我们使用StringBuilder对象sb来累积从BufferedReader读取的每一行数据。在循环结束后,我们将StringBuilder对象转换为字符串并返回。这样,Future.get()方法就可以获取到完整的API响应数据。

完整代码示例

import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*;  class StyleThreadDemo implements Callable<String>{      private Integer n;     public StyleThreadDemo(int a){         this.setN(a);     }     public String callApi() throws Exception {         StringBuilder sb = new StringBuilder();         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 );                 sb.append(output);             }              conn.disconnect();         }catch(Exception e) {             e.printStackTrace();         }         return sb.toString();     }      @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());         }         }  }

注意事项

  • 异常处理: 在实际应用中,需要更完善的异常处理机制,例如,在读取API响应时,应该处理IOException等异常。
  • 资源释放: 确保在使用完HttpURLConnection和BufferedReader后,正确关闭它们,释放资源。
  • 字符编码 在读取API响应时,需要注意字符编码问题,确保能够正确解析API返回的数据。

总结

当使用Future.get()方法获取结果为null时,需要仔细检查任务的返回值是否正确设置。对于从输入流读取数据的情况,可以使用StringBuilder累积读取到的数据,确保能够返回完整的结果。同时,要注意异常处理和资源释放,保证程序的稳定性和可靠性。通过以上方法,可以有效地解决Java多线程编程中使用Future.get()方法时遇到的结果为null的问题。

暂无评论

发送评论 编辑评论


				
上一篇
下一篇
text=ZqhQzanResources