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


     场景

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

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

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

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

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

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

    比如:

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

    执行效果为

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

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

            ArrayList<Future<String>> resultList = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                Future<String> submit = executorService.submit(new CustomTask());
                resultList.add(submit);
            }
            resultList.forEach(result -> {
                try {
                    System.out.println(result.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            });

    上面这种执行效果

    2、完整示例代码

    package com.ruoyi.demo.Executor;
    
    import com.ruoyi.common.utils.DateUtils;
    
    import java.util.ArrayList;
    import java.util.concurrent.*;
    
    public class CallableDemo {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            ArrayList<Future<String>> resultList = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                Future<String> submit = executorService.submit(new CustomTask());
                resultList.add(submit);
            }
            resultList.forEach(result -> {
                try {
                    System.out.println(result.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            });
        }
    }
    
    class CustomTask implements Callable<String> {
    
        @Override
        public String call() throws Exception {
            String threadName = Thread.currentThread().getName();
            System.out.println("线程名:" + threadName + " 开始时间:" + DateUtils.getTime());
            System.out.println("系统需要业务操作1秒");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "threadName = "+threadName +" 结束时间:"+DateUtils.getTime();
        }
    }
  • 相关阅读:
    《 动态规划_ 货币系统 》
    《动态规划_入门 LIS 问题 》
    数据库中左连接、右连接、全连接的区别
    http和https的区别与联系
    【复习周之流水账记录】
    web前端整套面试题(三)--网易的面试题
    微信小程序相关三、css写小黄人
    CSS选择器的匹配规则
    web前端整套面试题(二)--今日头条面试题
    有趣的逻辑题
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/16565199.html
Copyright © 2020-2023  润新知