• 多线程查询,效率翻倍


    参考链接: https://blog.csdn.net/le_17_4_6/article/details/118699111

    代码案例

    多线程工具类 提高执行线程和获取返回数据方法

    复制代码
    /**
     * 多线程工具类
     */
    public class ConcurrentUtil {
        /**
         * 执行任务
         *
         * @param <ResponseModel> 返回的结果集Future ResponseModel
         * @param executorService ExecutorService
         * @param callable 回调
         * @return Future ResponseModel
         */
        public static <ResponseModel> Future<ResponseModel> doJob(ExecutorService executorService, MyCallable callable) {
            return (Future<ResponseModel>) executorService.submit(callable);
        }
    
        /**
         * 获取结果集,执行时会阻塞直到有结果,中间的异常不会被静默
         *
         * @param future Future
         * @param <ResponseModel> 返回的结果集 ResponseModel
         * @return ResponseModel
         */
        public static <ResponseModel> ResponseModel futureGet(Future<ResponseModel> future) {
            try {
                return future.get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            }
        }
    }
    复制代码

     

    公共类

    复制代码
    /**
     * 响应结果类
     */
    @Data
    @ToString
    public class ResponseModel implements Serializable {
        //消息
        private String message;
        //状态码
        private int messageCode;
        //结果
        private Object result;
    
        public ResponseModel(String message, int messageCode, Object result) {
            this.message = message;
            this.messageCode = messageCode;
            this.result = result;
        }
    
        public ResponseModel() {
        }
    }
    复制代码

     

    复制代码
    public final class StFlag {
    
    
        public StFlag() {
        }
    
        /**
         * 性别:0-男,1-女
         */
        public static final String SEX_FLAG_0 = "0";
        public static final String SEX_FLAG_1 = "1";
    
        /**
         * 学生服务
         */
        public static final String STUDENT_SERVICE = "STUDENT";
        /**
         * 问卷服务
         */
        public static final String QUESTION_SERVICE = "QUESTION";
    }
    复制代码

     

    复制代码
    /**
     * 多线程业务类
     */
    @Slf4j
    @Setter
    public class MyCallable implements Serializable, Callable<ResponseModel> {
        //服务名
        private String whichServiceName;
        private StudentController studentController;
        private RequestStudentModel studentEntity;
    
    
        public MyCallable(String whichServiceName, StudentController studentController, RequestStudentModel studentEntity) {
            this.whichServiceName = whichServiceName;
            this.studentController = studentController;
            this.studentEntity = studentEntity;
        }
    
        @Override
        public ResponseModel call(){
    
            if (StFlag.STUDENT_SERVICE.equalsIgnoreCase(whichServiceName)){
                return studentController.getStudentList(studentEntity);
            }
            return studentController.getStudentList(studentEntity);
        }
    }
    复制代码

     

    复制代码
    /**
     * 学生相关控制器,真正业务类,具体业务了逻辑自己实现
     */
    @RestController
    @RequestMapping("/student")
    @Slf4j
    public class StudentController {
    
        @Autowired
        private StudentService studentService;
    
        /**
         * 查询问卷校验项
         * @return
         */
        @PostMapping("/getStudentList")
        public ResponseModel getStudentList(@RequestBody RequestStudentModel studentEntity){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new ResponseModel("查询成功", 200, "");
        }
    }
    复制代码

     

    测试主类

    特别注意, ConcurrentUtil.futureGet(responseRqestionFuture);方法要在所有线程执行完之后执行,否则达不到多线程执行的效果,因为future.get()会阻塞,知道拿到返回值

    复制代码
    /**
     * 多线程控制器
     */
    @RestController
    @RequestMapping("/concurrent")
    @Slf4j
    public class CurrentController {
        @Autowired
        private StudentController studentController;
        /**
         * 多线程测试
         * @return
         */
        @PostMapping("/current")
        public ResponseModel getStudentList(@RequestBody RequestStudentModel studentEntity) throws ExecutionException, InterruptedException {
            log.info("current   ---- start ");
            List list = new ArrayList();
            ExecutorService executorService = new ThreadPoolExecutor(2, 2, 3,
                    TimeUnit.SECONDS, new LinkedBlockingQueue<>(30), Executors.defaultThreadFactory(),
                    new ThreadPoolExecutor.CallerRunsPolicy());
    //        另一种方式创建线程池,不推荐,因为不能修改内部参数,比如队列类型
    //        ExecutorService executorService = Executors.newFixedThreadPool(20);
    //        多线程调用方式
    //        MyCallable myCallable= new MyCallable(StFlag.STUDENT_SERVICE,studentController, studentEntity);
    //        Future<ResponseModel> submit = executorService.submit(myCallable);
    //        ResponseModel responseModel1 = submit.get();
            long timeStart = System.currentTimeMillis();
            // 查询问卷
            Future<ResponseModel> responseRqestionFuture = ConcurrentUtil.doJob(executorService,
                    new MyCallable(StFlag.STUDENT_SERVICE,studentController, studentEntity));
            // 查询学生
            Future<ResponseModel> responseSudentFuture = ConcurrentUtil.doJob(executorService,
                    new MyCallable(StFlag.QUESTION_SERVICE,studentController, studentEntity));
            //future.get方法
            //线程池线程是异步提交的,但是返回分页结果是需要同步返回,Future的get是个阻塞方法。
            // 只有所有的任务全部完成,我们才能用get按照任务的提交顺序依次返回结果,
            // 调用future.get()方法查看线程池内所有方法是否已执行完成,达到线程异步提交,结果集同步返回的效果。
            ResponseModel myCallableResponseModel1 = ConcurrentUtil.futureGet(responseRqestionFuture);
            ResponseModel myCallableResponseModel2 = ConcurrentUtil.futureGet(responseSudentFuture);
            long timeMiddle = System.currentTimeMillis();
            long longMutiThread = timeMiddle - timeStart;
            log.info("多线程执行用时为: {}", longMutiThread);
            list.add("多线程执行用时为: "+longMutiThread);
            // 单线程查询
            ResponseModel responseModel = studentController.getStudentList(studentEntity);
            ResponseModel studentList = studentController.getStudentList(studentEntity);
            long timeEnd = System.currentTimeMillis();
            long longDingleThread = timeEnd - timeMiddle;
            log.info("单线程执行用时为: {}", longDingleThread);
            list.add("单线程执行用时为: "+longDingleThread);
            list.add(myCallableResponseModel1);
            list.add(myCallableResponseModel2);
            list.add(responseModel);
            list.add(studentList);
            log.info("current   ---- end ");
    
            return new ResponseModel("多线程测试完成", 200, list);
        }
    }
    复制代码

     

    测试案例

     

    POSTMan测试

     

     

    控制台打印

    2022-07-02 01:48:37.521 INFO  current   ---- start  【http-nio-8081-exec-2】【CurrentController:342022-07-02 01:48:39.552 INFO  多线程执行用时为: 2144 【http-nio-8081-exec-2】【CurrentController:602022-07-02 01:48:43.588 INFO  单线程执行用时为: 4028 【http-nio-8081-exec-2】【CurrentController:672022-07-02 01:48:43.589 INFO  current   ---- end  【http-nio-8081-exec-2】【CurrentController:73】

     

  • 相关阅读:
    Windows OpenGL 图像反色
    第一章 Linux及Linux Shell简介
    idea整合Tomcat进行Javaweb工程
    1040 有几个PAT (分数 25)【C++】
    SprinBoot+Vue民宿预约微信小程序的设计与实现
    MyBatis与MySql关系阐述
    Rust的derive思考
    Elasticsearch-汇总
    【系列教程】ChatGPT+ROS:打造智能无人机自主飞行的下一代解决方案✈️【一】将chatgpt集成到ROS中
    《java 桌面软件开发》swing 以鼠标为中心放大缩小移动图片
  • 原文地址:https://www.cnblogs.com/hikoukay/p/16436349.html