• Java中ExecutorService线程的Callable的future.get()方法堵塞当前线程解决方法


     场景

    Java中ExecutorService线程池的使用(Runnable和Callable多线程实现):

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126242904

    在上面学习线程池ExecutorService的使用,实现Callable接口,并获取返回结果时

    需要注意future的get()方法会堵塞当前线程的执行。

    即当前线程执行结束并获取到结果之后才会继续执行下个线程。

    这样就无法实现多线程的效果。

    比如:

    1. //        ArrayList resultList = new ArrayList<>();
    2. //        for (int i = 0; i < 5; i++) {
    3. //            Future submit = executorService.submit(new CustomTask());
    4. //            String result = null;
    5. //            try {
    6. //                result = submit.get();//get方法能获取到当前线程的执行结果,但是会堵塞当前线程
    7. //                resultList.add(result);
    8. //            } catch (InterruptedException e) {
    9. //                e.printStackTrace();
    10. //            } catch (ExecutionException e) {
    11. //                e.printStackTrace();
    12. //            }
    13. //        }

    执行效果为 

    注:

    博客:
    霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    1、解决方式为创建一个数组存储所有的future,在所有线程循环结束以后再遍历list获取结果。

    1.         ArrayList> resultList = new ArrayList<>();
    2.         for (int i = 0; i < 5; i++) {
    3.             Future submit = executorService.submit(new CustomTask());
    4.             resultList.add(submit);
    5.         }
    6.         resultList.forEach(result -> {
    7.             try {
    8.                 System.out.println(result.get());
    9.             } catch (InterruptedException e) {
    10.                 e.printStackTrace();
    11.             } catch (ExecutionException e) {
    12.                 e.printStackTrace();
    13.             }
    14.         });

    上面这种执行效果

     

    2、完整示例代码

    1. package com.ruoyi.demo.Executor;
    2. import com.ruoyi.common.utils.DateUtils;
    3. import java.util.ArrayList;
    4. import java.util.concurrent.*;
    5. public class CallableDemo {
    6.     public static void main(String[] args) {
    7.         ExecutorService executorService = Executors.newFixedThreadPool(5);
    8.         ArrayList> resultList = new ArrayList<>();
    9.         for (int i = 0; i < 5; i++) {
    10.             Future submit = executorService.submit(new CustomTask());
    11.             resultList.add(submit);
    12.         }
    13.         resultList.forEach(result -> {
    14.             try {
    15.                 System.out.println(result.get());
    16.             } catch (InterruptedException e) {
    17.                 e.printStackTrace();
    18.             } catch (ExecutionException e) {
    19.                 e.printStackTrace();
    20.             }
    21.         });
    22.     }
    23. }
    24. class CustomTask implements Callable {
    25.     @Override
    26.     public String call() throws Exception {
    27.         String threadName = Thread.currentThread().getName();
    28.         System.out.println("线程名:" + threadName + " 开始时间:" + DateUtils.getTime());
    29.         System.out.println("系统需要业务操作1秒");
    30.         try {
    31.             Thread.sleep(1000);
    32.         } catch (InterruptedException e) {
    33.             e.printStackTrace();
    34.         }
    35.         return "threadName = "+threadName +" 结束时间:"+DateUtils.getTime();
    36.     }
    37. }

  • 相关阅读:
    Android开发笔记消息推送SDK
    读写分离技术架构图
    Android 10.0系统settings app详情页控制开启关闭流量数据的开关
    大语言模型(LLM)综述(四):如何适应预训练后的大语言模型
    Redis主从模式下过期数据和数据不一致
    数据挖掘——机器学习
    【记录】数据处理方法总结及实现
    Vue中如何进行瀑布流布局与图片加载优化
    大老耗时90天完成,带你从实践出发,深入学习Mycat中间件,拥抱Mycat
    Worthington用于细胞收获的胰蛋白酶&细胞释放程序
  • 原文地址:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126243463