首页 > 解决方案 > CompletableFuture 以及使用 FileReader 读取,程序不会退出

问题描述

背景

构建一个数据管道,接收到的每条消息都将被异步处理。试图通过以下方式模拟行为

代码

 BufferedReader reader = null;
 ExecutorService service = Executors.newFixedThreadPool(4);
 try {
   String filepath = str[0];
   FileReaderAsync fileReaderAsync = new FileReaderAsync();
   reader = new BufferedReader(new FileReader(filepath));
   Random r = new Random();
   String line; 
   while ((line = reader.readLine()) != null) {
          Integer val = Integer.valueOf(line.trim());
          int randomInt = r.nextInt(5);
          Thread.sleep(randomInt * 100);
          CompletableFuture.supplyAsync(() -> {
              System.out.println("Square : " + val);
              return val * val;
          }, service) 
             .thenApplyAsync(value -> {
                  System.out.println(":::::::Double : " + value);
                  return 2 * value;
              }, service)
              .thenAccept(value -> {
                   System.out.println("Answer : " + value);
              });
   }
 } catch (Exception e) {
     e.printStackTrace();
 } finally {
     try {
          reader.close();
     } catch (Exception e) {
          throw new RuntimeException(e.getMessage());
     }
 }

为简单起见,仅粘贴主方法代码,假设变量已声明并在范围内。

问题

代码

设计

编辑 1 添加

public void shutdown() {
   service.shutdown();
}

  reader.close();
  fileReaderAsync.shutdown();

这成功了。

标签: javafileasynchronouscompletable-future

解决方案


池中有 4 个线程,但 Thread.sleep() 会阻塞主线程。您的程序读取一行,最多块。5 秒,然后将触发异步代码,这根本不需要任何异步,实际上会产生巨大的开销。

不要在异步程序中使用 Thread.sleep()。

但我试图了解你的代码,我可以提供这个:

public int calcWork(final int x) {
    return x*x;
}

public void iter_async_rec(final BufferedReader reader) {
    String line = reader.readline();
    if (line != null) {     
         int i = Integer.tryParse(line); // checks required       
         CompetableFuture.supplyAsync(calcWork(i))
         .thenSupplyAsync(i->System.out.println(i))
         .thenRunAsync(()->iter_asnc_rec(reader))
    }
}

另外:大多数时候,只使用标准执行器是最好的选择。相反,给定的样本不会提高速度。

也许看看反应的想法!?反应式Java


推荐阅读